Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambdas in variadic templates

Using Microsoft Visual C++ 2013 (12.0), I am encountering compile-time errors when using a lambda in a constructor in a variadic template. I have managed to boil it down as shown below (see the lines with the error comments). It appears to be a bug in 12.0 that is not present in 14.0. I haven't tried other versions. Is there any documentation on this bug, perhaps in the form of a release note that clarifies the conditions under which this bug occurs and which states that it has been explicitly fixed?

#include <functional>

// a simple method that can take a lambda
void MyFunction(const std::function<void()>& f) {}

// a simple class that can take a lambda
class MyClass
{
public:
    MyClass(const std::function<void()>& f) {}
};

// non-templated test
void test1()
{
    MyFunction([] {}); // OK
    MyClass([] {}); // OK
    MyClass o([] {}); // OK
}

// non-variadic template test
template<typename T>
void test2()
{
    MyFunction([] {}); // OK
    MyClass([] {}); // OK
    MyClass o([] {}); // OK
}

// variadic template test
template<typename... T>
void test3()
{
    MyFunction([] {}); // OK
    MyClass([] {}); // OK
    MyClass a([] {}); // error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
                      // error C2440: 'initializing' : cannot convert from 'test3::<lambda_12595f14a5437138aca1906ad0f32cb0>' to 'int'

    MyClass b(([] {})); // putting the lambda in an extra () seems to fix the problem
}

// a function using the templates above must be present
int main()
{
    test1();
    test2<int>();
    test3<int, int, int>();
    return 1;
}

Edit/Update: MSVC 2013 compiler seem to have this bug, latest versions fixed that. GCC and clang compilers don't show any error.

like image 548
Michael Gunter Avatar asked Sep 07 '25 10:09

Michael Gunter


1 Answers

I can't say is that bug or not, back days Microsoft was not so eager to latest C++ standards, it was two steps behind GCC and CLang, and it's not a surprise to know that no-one implement a whole standard in one compiler update. Some stuff from std library may be partially implemented, for example Visual Studio usually implements new features under std::experimental namespace (filesystem for VS2013), but something like compiler lexemes can't be added that way.

For common information about standard compatibility I suggest to use compiler support article https://en.cppreference.com/w/cpp/compiler_support/11 (MSVC means _MSC_VER definition) and https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance more for detailed information about Visual Studio. Here https://en.wikipedia.org/wiki/Microsoft_Visual_C++#Internal_version_numbering you can find _MSC_VER version along with related Visual Studio version, source is https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros.

Based on those articles I believe that your problem lays in between "Variadic templates" and "Lambda expression" both are fully supported from Visual Studio 19.0, searching _MSC_VER 1900 in wiki that means Visual Studio 2015 (Update 2, if to be precise according to Microsoft article).

like image 156
Liastre Avatar answered Sep 08 '25 23:09

Liastre