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

标签 c++ visual-c++ gcc c++11

哪个(如果不是两个)违反规范?在 MSVC 2013 和 MSVC Nov 2013 CTP 上尝试使用 MSVC,GCC 是 MinGW x64 4.9.1 with -std=c++11。

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 类型的方式不同,以及他们考虑定义变量的时间。

最佳答案

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

关于c++ - 与 GCC/MSVC 中的 lambda 转换构造函数不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26222812/

相关文章:

windows - 我应该在 64 位版本中同时定义 _WIN32 和 _WIN64 吗?

c++ - 从指针有条件地初始化 std::vector

c++ - 为什么这个虚拟调用模棱两可?

linux - 适用于 Linux 的 Visual C++ : copy content files to build directory?

c - gcc 使用函数指针消除死代码

c++ - 软件预取手册说明合理时的方案

c++ - 内存碎片整理在 64 位系统上是否仍然相关

c++ - 什么 Linux 全文索引工具有好的 C++ API?

c++ - std::unique_ptr 是为数组分配内存的错误工具吗?

visual-c++ - 将 C++ OpenCV 程序移植到 Ubuntu