Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can 'auto' be used as a subtype of lambda argument in C++?

Tags:

c++

lambda

C++ code with auto as a part of lambda argument type is accepted by GCC, e.g.:

#include <vector>
#include <iostream>

int main()
{
    auto make_vector = []( std::initializer_list<auto> v ) 
        { return std::vector<typename decltype(v)::value_type>{v}; };
    auto v = make_vector( {1,2} );
    std::cout << v[0] << ' ' << v[1] << '\n';
}

https://gcc.godbolt.org/z/z43bEjMc9

Here the argument type is std::initializer_list<auto> and it is really convenient sometimes. But other compilers complain:

A template-argument cannot be a type that contains 'auto'

Is it a GCC-only extension of the language or a new C++ feature that will appear in other compilers as well? If the first is the case then how can it be turned off to maximize language conformance?

like image 737
Fedor Avatar asked Jul 17 '21 08:07

Fedor


People also ask

Which C++ Auto was limited to lambda functions?

C++14 allows lambda function (Generic lambda function) parameters to be declared with the auto.

What is the type of lambda expression in C++?

The type of a lambda expression is unspecified. But they are generally mere syntactic sugar for functors. A lambda is translated directly into a functor.


2 Answers

It looks like it's a bug in GCC. Altough it says it's solved in the version of GCC you're using...

You can read here more on why you can't use auto in this context.

It was correctly pointed out to me that this case is for a function parameter. It's still not allowed in C++20, see this answer.

like image 51
ShadowMitia Avatar answered Oct 22 '22 09:10

ShadowMitia


This is not the valid way to declare generic lambdas. [dcl.spec.auto.general]/2:

A placeholder-type-specifier of the form type-constraintopt auto can be used as a decl-specifier of the decl-specifier-seq of a parameter-declaration of a function declaration or lambda-expression and, if it is not the auto type-specifier introducing a trailing-return-type (see below), is a generic parameter type placeholder of the function declaration or lambda-expression.

Note that std::initializer_list<auto> is not in the form of type-constraintopt auto.

Since C++20 you can delcare template parameter list for generic lambdas. E.g.

auto make_vector = []<typename T>( std::initializer_list<T> v ) 
    { return std::vector<typename decltype(v)::value_type>{v}; };
like image 26
songyuanyao Avatar answered Oct 22 '22 07:10

songyuanyao