与 GCC/MSVC 中的 lambda 转换构造函数的差异
Posted
技术标签:
【中文标题】与 GCC/MSVC 中的 lambda 转换构造函数的差异【英文标题】:Discrepancy with lambda conversion constructor in GCC/MSVC 【发布时间】:2014-10-06 18:51:00 【问题描述】:如果不是两者,哪一个违反规范?在 MSVC 2013 和 MSVC Nov 2013 CTP 上尝试使用 MSVC,GCC 是带有 -std=c++11 的 MinGW 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];
;
这似乎源于他们处理 lambda 类型的方式不同,以及他们考虑定义变量的时间。
【问题讨论】:
相关:***.com/questions/2067988/… 【参考方案1】:GCC 是对的。
对于您的第一个表单:
一个变量被认为是在它的声明符的末尾声明的,它在它的初始化器之前。这就是为什么这个表格是有效的。著名的例子是int i = 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 类型上定义的转换函数,而不是是定义附加标准转换的语言中的特殊规则。 我在寻找报价,我明白了,有道理。以上是关于与 GCC/MSVC 中的 lambda 转换构造函数的差异的主要内容,如果未能解决你的问题,请参考以下文章