auto parameter type in functions
Ok, so thanks to Piotr pointing this other question asking about the same thing, I found the information in a comment that will resolve this, here it is:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4040.pdf
page 16, chapter 5.1.1 named generic functions
A generic function is a function template whose
template-parameter-list has a parameterdeclaration whose
type-specifier is either auto or a constrained-type-name.[ Example:
auto f(auto x); // Ok
void sort(C& c); // Ok (assuming C names a concept)
— end example ]
This seems rather positive :)
followed by the excpected obvious wording, that matches generic lambda:
The declaration of a generic function has a template-parameter-list
that consists of one invented type template-parameter for each
occurrence of auto.[ Example: The following generic function declarations are equivalent:
template<typenaem T>
conxtexpr bool C() { ... }
auto f(auto x, const C& y);
template<typename T1, C T2>
auto f(T1 x, const T2& y);
The type of y is a type parameter constrained by C. — end example ]
Usage of auto concerning templates and functions
No.
You need to explicitly use
template
, unless your compiler allows it as an extension. It might come in C++17.Is auto as a parameter in a regular function a GCC 4.9 extension?
You probably want to take the functor/function-pointer by universal reference.
You forgot to decay the
vector
's element-type.Your loop has a loop-variable of type
int
. Whether that is enough...
template<class F>
auto returnN(F&& gen, size_t n) {
std::vector<std::decay_t<decltype(gen())>> vec; // Needs to decay
while(n--)
vec.push_back(gen());
return vec;
}
Use of auto as return and parameters type in C++14
To start with, your code makes use of gcc extension, namely auto function parameters.
I guess your gcc version does not work with the extension properly and provides an incorrect result (with gcc 7.1 I have 0.67 0.67
even using auto parameters).
The normal way to rewrite your function in a standard C++ is to apply templates:
template<typename T, typename U>
auto multiplication(T a, U b)
{
return a * b;
}
and let the compiler to deduce return type.
Parameter packs and function declaration
Using auto
as a function parameter is not Standard C++. Your code is currently not valid C++. See Is auto as a parameter in a regular function a GCC 4.9 extension? for more information. Note that auto
as a function parameter (along with shorthand concept syntax) was not added to C++20's working draft yet.
Regardless, using auto
in that manner is just shorthand for function template definition - this means that your need to define your function in the header.
Here's a solution that's valid C++:
// lib.h
template <typename... Js>
void funcN(int i, Js... js) {
}
More information: Why can templates only be implemented in the header file?
Are there negative ramifications of using auto as a parameter?
Yes, there are. They are forbidden by current C++ standard.
void Call( auto & fp )
is a compilation error on standard-conforming compiler.
Is this a bug in g++ c++14 support?
As stated by @SergeyA, this is a GCC bug. std::vector<auto>
should not have been accepted.
auto type deduction for argument with default value
Should I be able to declare a function parameter as auto while still being able to give it a default value in C++11 or C++14?
I don't know if C++17 support it but, as far I know, C++11 and C++14 don't support an auto
parameter for a function (C++14 support it only for lambda functions)
I thought the given default value would be enough to let compiler deduce the parameter type...
If instead of auto
you accept to use a template type, you have to add the default template type also.
Something as follows
template <typename T = decltype(PrintColour::COLOUR_1)>
void colour( T c = PrintColour::COLOUR_1 )
{
switch ( c )
{
case PrintColour::COLOUR_1:
std::cout << "Colour 1" << std::endl;
break;
case PrintColour::COLOUR_2:
std::cout << "Colour 2" << std::endl;
}
}
I know: is redundant.
-- EDIT --
The OP says
I was just wondering if I couldn't make my code more readable by not repeating
More readable probably not but... if you want it not repeating... I know that macros are distilled evil but... if you really want avoid repeating...
#define noRepeat(r, n, a, b) \
r n (decltype(b) a = b)
noRepeat(void, colour, c, PrintColour::COLOUR_1)
{
switch ( c )
{
case PrintColour::COLOUR_1:
std::cout << "Colour 1" << std::endl;
break;
case PrintColour::COLOUR_2:
std::cout << "Colour 2" << std::endl;
}
}
or also (if you want make the trick on parameter basis)
#define parDef(a, b) decltype(b) a = b
void colour ( parDef(c, PrintColour::COLOUR_1), parDef(d, 5) )
{
switch ( c )
{
case PrintColour::COLOUR_1:
std::cout << "Colour 1" << std::endl;
break;
case PrintColour::COLOUR_2:
std::cout << "Colour 2" << std::endl;
}
}
Related Topics
Template Issue Causes Linker Error (C++)
Difference Between Try-Catch Syntax for Function
Do I Need to Explicitly Call the Base Virtual Destructor
Std::Lock_Guard or Std::Scoped_Lock
Borderless Window Using Areo Snap, Shadow, Minimize Animation, and Shake
Why Can't We Pass Arrays to Function by Value
Why Isn't 'Int Pow(Int Base, Int Exponent)' in the Standard C++ Libraries
Memset() or Value Initialization to Zero Out a Struct
How to Use If (Pointer) Instead of If (Pointer != Null)
Getting Libcurl to Work with Visual Studio 2013
Why Do I Need to Use Typedef Typename in G++ But Not VS
Are Function Static Variables Thread-Safe in Gcc
Why Do You Use Std::Move When You Have && in C++11
Passing a Std::Array of Unknown Size to a Function
Checking for an Empty File in C++
When Is It Best to Use the Stack Instead of the Heap and Vice Versa