2014-10-06 49 views
4

哪一個,如果不是兩個,都打破規範?在MSVC 2013和MSVC Nov 2013 CTP上使用MSVC,GCC爲MinGW x64 4.9.1,使用-std = C++ 11。GCC/MSVC中λ轉換構造函數的差異

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類型的方式不同,並且他們考慮定義一個變量。

+0

相關:https://stackoverflow.com/questions/2067988/recursive-lambda-functions-in-c0x – 2014-10-06 19:03:47

回答

5

GCC是正確的。

爲了您的第一種形式:

一個變量被認爲是在其聲明符,這是它的初始化器前的最後聲明。這就是爲什麼這個表格是有效的。着名的例子是int i = i;,它在語法上是有效的,並用它自己的(不確定的)值初始化i

關於你的第二形態:

,因爲你有兩個用戶自定義轉換您與=初始化失敗。 (λ類型的轉換運算符被認爲是用戶定義的。)這是類似於

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

@ShafikYaghmour它從標準如何描述轉換(5.1.2p6)開始,如果我正確理解你的問題:它被定義爲在lambda類型上定義的轉換函數,而不是定義額外標準的語言中的特殊規則轉換。 – hvd 2014-10-06 20:24:43

+0

我一直在尋找報價,我認爲它是有道理的。 – 2014-10-06 20:27:09

相關問題