Reputation: 2176
I understand that using templates
is one of the appreciated way of overloading but i was wondering why auto
cannot be used for function parameter type deduction hence aiding overloading of the function?
N3690
says in 7.6.1.4/3 that lambda expression can be made generic using auto,providing this example
auto glambda = [](int i, auto a) { return i; };//OK: a generic lambda
(note: this is not mentioned in N3485)
1).why cant i do a similar thing for a normal function for e.g
void swap(auto& param1, decltype(param1)& param2)
{
decltype(param1) temp = param1;
param1 = param2;
param2 = temp;
}
this gives errors error : parameters declared auto
.
from N3690 7.1.6.4/4
The type of a variable declared using auto or decltype(auto) is deduced from its initializer. This use is allowed when declaring variables in a block (6.3), in namespace scope (3.3.6), and in a for-init-statement (6.5.3).[...]
am i wrong in assuming that the param1
and param2
fall under block scope and hence eligible for auto deduction?
2). if such feature was allowed what would be the pitfalls?
i'm using gcc 4.8.1.
Thank you
Upvotes: 15
Views: 2734
Reputation: 24606
N3690 is the committee draft for C++14, i.e. for the next C++ standard that has yet to be released and wich might not be implemented yet in most compilers. So you should refer to your compiler's documentation if generic lambdas are implemented - I guess they are not.
However, with gcc you have good chances that C++14 features will be implemented before the new standard is officially released, though you might have to explicitly enable C++14 support with a command line flag. Looking at the docs it should be -std=gnu++1y
According to this site, generic lambdas are not implemented yet in GCC.
Update:
As for normal generic functions using auto
parameters: These don't exist and won't be coming for the next time. The reason is that templated functions are only slightly more verbose to type and more powerful, since you can refer to the types and directly apply template metafunctions to them. In generic lambdas this can be done only by using decltype(a)
, wich is a bit more tedious and has to be used with care, because it behaves a bit different than template argument deduction.
An additional bonus with templates compared to auto params is a bit more typesafety or expressiveness:
void func(auto a, auto b); //a and b might be different types
template <class T>
void func(T a, T b); //a and b must be the same type
Upvotes: 2
Reputation: 30035
There is already a way to write what you wanted :-
template <class T>
void swap(T& param1, T& param2)
{
T temp = param1;
param1 = param2;
param2 = temp;
}
So why create a new syntax that doesn't let you do anything you couldn't do before. The suggested change to lambdas are to allow generic lambdas which you couldn't do before, and I guess any syntax using the template syntax would have been ugly here.
Upvotes: 0
Reputation: 20523
Why cant i do a similar thing for a normal function for e.g
void swap(auto& param1, decltype(param1)& param2)
Simply because the language doesn't allow this. Before auto
was (re)invented in C++11 what you want was achievable through templates:
template <class T, class U>
void swap(T& param1, U& param2);
C++11 also brough lambda expressions and C++14 is likely to introduce polymorphic lambdas which are, basically, lambdas whose operator ()
are templates. A syntax similar to that of templates was considered for the polymorphic lambdas, for instance (example taken from N3418)
[]<class T>(T* p) { /* ... */ }
At the end, the prefered syntax was using auto
rather than introducing a template parameter list.
It's true that one could consider extend this terser syntax to function templates (as the OP suggests) but, as far as I know, the committee hasn't considered this possibility. It might do in the future but someone has to formally propose it. This might be a "nice feature to have" but IMHO this is just syntactic sugar that doesn't bring much to the language.
Also, I can't see how this terser syntax (with no template parameter lists) could be used for template classes and perhaps diverging the syntax for template functions from that of template classes is not worth doing.
Upvotes: 1
Reputation: 55887
n3690 7.1.6.4/2
7.1.6.4/3The placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid.
7.1.6.4/4If the auto type-specifier appears as one of the decl-specifiers in the decl-specifier-seq of a parameter- declaration of a lambda-expression, the lambda is a generic lambda.
7.1.6.4/5The type of a variable declared using auto or decltype(auto) is deduced from its initializer. This use is al- lowed when declaring variables in a block (6.3), in namespace scope (3.3.6), and in a for-init-statement (6.5.3). auto or decltype(auto) shall appear as one of the decl-specifiers in the decl-specifier-seq and the decl- specifier-seq shall be followed by one or more init-declarators, each of which shall have a non-empty initial- izer.
Only such usage is alowed. Any other usage is prohibited (in particular usage inA placeholder type can also be used in declaring a variable in the condition of a selection statement (6.4) or an iteration statement (6.5), in the type-specifier-seq in the new-type-id or type-id of a new-expression (5.3.4), in a for-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition (9.4.2).
parameter-declaration-clause
).
7.1.6.4/6
A program that uses auto or decltype(auto) in a context not explicitly allowed in this section is ill-formed.
Upvotes: 5