可变模板中的lambda

Lambdas in variadic templates

本文关键字:lambda      更新时间:2023-10-16

使用Microsoft Visual c++ 2013 (12.0),我在可变模板的构造函数中使用lambda时遇到编译时错误。我已经设法将其归结为如下所示(参见error评论的行)。这似乎是12.0中不存在的14.0中的错误。我还没试过其他版本。是否有关于这个bug的文档,也许以发布说明的形式,澄清这个bug发生的条件,并声明它已经被明确修复?

#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;
}

编辑/更新: MSVC 2013编译器似乎有这个错误,最新版本修复。

我不能说这是不是bug,过去微软对最新的c++标准并不那么热衷,它比GCC和CLang落后两步,而且知道没有人在一次编译器更新中实现完整的标准也不足为奇。std库中的一些东西可以部分实现,例如Visual Studio通常在std::experimental命名空间(VS2013的文件系统)下实现新功能,但像编译器lexeme这样的东西不能这样添加。

关于标准兼容性的常见信息,我建议使用编译器支持文章https://en.cppreference.com/w/cpp/compiler_support/11 (MSVC表示_MSC_VER定义)和https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance了解更多关于Visual Studio的详细信息。在这里https://en.wikipedia.org/wiki/Microsoft_Visual_C++#Internal_version_numbering你可以找到_MSC_VER版本以及相关的Visual Studio版本,来源是https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros。

根据这些文章,我相信你的问题在于"可变模板"。和"Lambda表达式;两者都完全支持Visual Studio 19.0,在wiki中搜索_MSC_VER 1900,这意味着Visual Studio 2015(更新2,如果根据微软文章精确)。

vs2015可以正常编译,因为vs2015可以完全支持c++11标准,你可以考虑升级你的vs