Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与GCC/MSVC中的lambda转换构造函数不一致_C++_Visual C++_Gcc_C++11 - Fatal编程技术网

C++ 与GCC/MSVC中的lambda转换构造函数不一致

C++ 与GCC/MSVC中的lambda转换构造函数不一致,c++,visual-c++,gcc,c++11,C++,Visual C++,Gcc,C++11,哪一个(如果不是两个)违反了规范?在MSVC 2013和MSVC 2013年11月CTP上使用MSVC进行了尝试,GCC使用-std=c++11命名为x64 4.9.1 template<typename ret_type> class memoizer { using func_type = ret_type(*)(const int); const func_type func; std::map<int, ret_type> cache;

哪一个(如果不是两个)违反了规范?在MSVC 2013和MSVC 2013年11月CTP上使用MSVC进行了尝试,GCC使用-std=c++11命名为x64 4.9.1

template<typename ret_type>
class memoizer
{
    using func_type = ret_type(*)(const int);
    const func_type func;

    std::map<int, ret_type> cache;

public:
    memoizer(func_type func) : func(func)
    {
    }

    ret_type operator [](const int n)
    {
        const auto it = cache.find(n);
        if(it != cache.end())
            return it->second;

        return cache[n] = func(n);
    }
};

//works in GCC but not MSVC
//error C2065: 'fib' : undeclared identifier
memoizer<int64_t> fib([](const int n)
{
    return n < 2 ? n : fib[n - 1] + fib[n - 2];
});

//works in MSVC but not GCC
//error: conversion from '<lambda(int)>' to non-scalar type 'memoizer<long long int>' requested
memoizer<int64_t> fib = [](const int n)
{
    return n < 2 ? n : fib[n - 1] + fib[n - 2];
};
模板
类记忆器
{
使用func_type=ret_type(*)(常量int);
常量func_类型func;
地图缓存;
公众:
记忆设定项(func_类型func):func(func)
{
}
ret_类型运算符[](常量int n)
{
const auto it=cache.find(n);
if(it!=cache.end())
返回->秒;
返回缓存[n]=func(n);
}
};
//在GCC中工作,但在MSVC中不工作
//错误C2065:“fib”:未声明的标识符
记忆器fib([](常量int n)
{
返回n<2?n:fib[n-1]+fib[n-2];
});
//适用于MSVC,但不适用于GCC
//错误:请求从“”转换为非标量类型“Memorizer”
记忆器fib=[](常量int n)
{
返回n<2?n:fib[n-1]+fib[n-2];
};
<>这似乎源于他们处理lambda类型的方式不同,当他们考虑变量定义时。

GCC是正确的。

第一张表格:

变量被认为是在其声明符的末尾声明的,该声明符在其初始值设定项之前。这就是本表格有效的原因。著名的例子是
inti=i
,它在语法上是有效的,并用自己的(不确定)值初始化
i

第二张表格:

使用
=
初始化失败,因为您有两个用户定义的转换。(lambda类型的转换运算符被认为是用户定义的。)它类似于

struct A { };
struct B { B(A) { } };
struct C { C(B) { } };
A a;
C c1(a); // okay
C c2 = a; // error

相关:@ShafikYaghmour如果我正确理解您的问题,它只是从标准如何描述转换(5.1.2p6)中得出的结论:它被定义为在lambda类型上定义的转换函数,而不是定义附加标准转换的语言中的特殊规则。我正在寻找引用,我看到了,有道理。