Home > other >  Can't Pass `std::array` From Within Closure
Can't Pass `std::array` From Within Closure

Time:10-26

Using the following declarations:

#include <array>

template <typename V> void makeError(V& v) {}

the following code snippet fails to compile under MSVC 16.11.13 with /std:c 17:

int main() {
    [&]() {
        std::array bugs{0};
        [&]() { makeError(bugs); };
    };
    return 0;
}

The error message is as follows: main.cpp(9,5): error C2955: 'std::array': use of class template requires template argument list

The same code compiles perfectly fine under GCC 10.4 with --std=c 17. The real problem came up when I tried removing the inner closure:

int main() {
    [&]() {
        std::array bugs{0};
        makeError(bugs);
    };
    return 0;
}

Or the outer closure:

int main() {
    std::array bugs{0};
    [&]() { makeError(bugs); };
    return 0;
}

Both of these compile happily under MSVC and GCC.

Is the first snippet invalid C ? If so, what part of the standard am I violating?

CodePudding user response:

Looks like this is a bug in msvc's legacy lambda processor. Your code compiles if you pass /Zc:lambda: https://godbolt.org/z/91z4chhTx

This seems to be the matching bug report: https://developercommunity.visualstudio.com/t/class-template-argument-deduction-fails-in-the-bod-1/414204

How I found this

I would always recommend using godbolt in cases like this, since it allows you to quickly switch between compilers, versions and command line args.

If something smells like a compiler bug, checking the latest versions is always a good idea. If something compiles under gcc & clang, but not msvc, it smells like a compiler bug.

I tried your code in the latest msvc and since it involves lambdas and captures, I remembered that there were changes to that in c 20, so I tried compiling as such. Since that worked, I had look through cppreference to see if I could find any relevant change to the standard that might legitimately cause this. I didn't find any, but then remembered that msvc has also constantly be increasing its standards conformance over the recent years.

So I used /permissive- with c 17 and once I noticed that this builds, I had a look through the conformance flags and found /Zc:lambda.

This confirmed this as a fixed compiler bug to me. And fixed bugs often have bug reports, so I googled the keywords that seemed relevant to the situation: msvc nested lambdas template deduction. The bug report is the second result for me.

  • Related