Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda copying a reference to a lambda reference VS2017 compile error

Tags:

c++

lambda

Compiling the following code in Visual Studio 2017:

#include "pch.h"
#include <iostream>

int main()
{
    int test = 5;

    auto cb1 = [test]()
    {
        auto cb2 = [&]()
        {
            auto cb3 = [test]()
            {
                std::cout << test;
            };
            cb3();
        };
        cb2();
    };
    cb1();
}

Gives the compiler error

test.cpp(17): error C2440: '<function-style-cast>': cannot convert from 'const int' to 'main::<lambda_80fd0d4feae1377a5d8b8955e10105ab>::()::<lambda_38fc83ae6a7bd6540ebe1721869db4f1>'
test.cpp(17): note: No constructor could take the source type, or constructor overload resolution was ambiguous
test.cpp(18): error C3536: 'cb2': cannot be used before it is initialized
test.cpp(18): error C2064: term does not evaluate to a function taking 0 arguments

Does anybody know why Visual Studio gives this error? (it seem to compile ok on clang) You can get it to compile by replacing auto cb2 = [&]() with auto cb2 = [&test]() why does that fix the errors?

Even more interesting adding std::cout << test; or const int &ref = test; to the body of cb2 fixes the compiler error.

like image 329
David Fooks Avatar asked Mar 26 '19 15:03

David Fooks


1 Answers

This is just a bug in older Visual Studio compilers. One can see experimentally that the error was present till MSVC v16.10, and it was fixed in MSVC v16.11. Fortunately, modern compilers including Visual Studio 2019 accept your program. Demo: https://gcc.godbolt.org/z/rYG7Ma8n9

like image 89
Fedor Avatar answered Sep 18 '22 12:09

Fedor