If my template type occurs first as an argument to lambda, MSVC causes a strange error

Consider this code:

#define SOLUTION 0

template <class T>
constexpr int one = 1;

template <class T>
struct A {
    static constexpr int o = one<A<T>>;

    void call() {
        static_assert(one<A<T>> == 1, "Failure");
    }
};

int main() {
#if SOLUTION
    A<int> object;
#endif

    [](A<int> a) {
        a.call();
    };

    return 0;
}

It successfully creates here, on ideone , regardless of the value of SOLUTIONdefine.

Now I know that this code is not very practical, but this is because I tried to find a minimal working example of this strange behavior. If I build it using the latest Visual Studio 2017 (platform toolset v141, _MSC_VER = 1910), I get the following error:

1>source.cpp(11): error C2131: expression did not evaluate to a constant
1>source.cpp(11): note: failure was caused by a read of an uninitialized symbol
1>source.cpp(11): note: see usage of 'one<A<int>>'
1>source.cpp(10): note: while compiling class template member function 'void A<int>::call(void)'
1>source.cpp(21): note: see reference to function template instantiation 'void A<int>::call(void)' being compiled
1>source.cpp(21): note: see reference to class template instantiation 'A<int>' being compiled

Oddly enough, when I put 1 for the macro SOLUTION, it will work successfully. The only difference is that an unused variable is A<int> object;defined in scope mainbefore the compiler reaches the lambda definition.

It is also fine if I define a function like this before main:

void f(A<int>& a) {
    a.call();
}

, .

?

+4
1

Ajay:

VS2017 3, (RTM) 2

. , , , .

0

Source: https://habr.com/ru/post/1678341/


All Articles