Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why auto cannot be used to overload functions?

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

like image 615
Koushik Shetty Avatar asked Jun 21 '13 09:06

Koushik Shetty


People also ask

In which we Cannot overload the function?

In which of the following we cannot overload the function? Explanation: While overloading the return function, it will rise a error, So we can't overload the return function.

Why we Cannot overload function on the basis of return type?

The return type of a function has no effect on function overloading, therefore the same function signature with different return type will not be overloaded. Example: if there are two functions: int sum() and float sum(), these two will generate a compile-time error as function overloading is not possible here.

What are the restrictions on overloaded function?

Restrictions on overloadingAny two functions in a set of overloaded functions must have different argument lists. Overloading functions that have argument lists of the same types, based on return type alone, is an error.

Can you overload functions?

Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading.

Is it possible to overload a function?

— Function declarations that differ only in the return type cannot be overloaded. And regarding your library, each function might belong to a different namespace or else it ain't possible either. Not the answer you're looking for?

Can You overload based on the return type in C++?

There's only one function in C++ that can be overloaded by return type, the implicit conversion operator special function, named operator T () (with T varying). Show activity on this post. No, you can't overload based on the return type. — Function declarations that differ only in the return type cannot be overloaded.

Why assignment operator is restricted to be overloaded as friend function?

Hence, to avoid modifying constant as LValue, assignment operator was restricted to be overloaded as friend function. // Just for the shake of understanding the issue. // MODIFYING A CONSTANT.

Can an operator overload be virtual in Java?

The operator overload can’t be virtual itself (only member functions can be virtual) but since it receives the foo by reference, virtual dispatch will still apply when it invokes write. (and, of course, the same applies equally to operator>> and a read member function).


3 Answers

n3690 7.1.6.4/2

The 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/3

If 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/4

The 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.

7.1.6.4/5

A 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).

Only such usage is alowed. Any other usage is prohibited (in particular usage in 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.

like image 93
ForEveR Avatar answered Oct 07 '22 07:10

ForEveR


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
like image 33
Arne Mertz Avatar answered Oct 07 '22 07:10

Arne Mertz


On top of ForEveR's answer:

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.

like image 1
Cassio Neri Avatar answered Oct 07 '22 06:10

Cassio Neri