2016-07-08 65 views
2

我有一個奇怪的錯誤,我真的不明白,VS2013。 這只是我的真正問題導致相同的錯誤簡化。沒有可執行此轉換的用戶定義轉換運算符,或者不能調用運算符

std::function<bool()> x = (someCondition == true) 
    ? []() { return true; } 
    : []() { return false; }; 

VS編譯器錯誤是:

1>f:\test\cppconsoleapplication\cppconsoleapplication.cpp(497): error C2446: ':' : no conversion from 'main::<lambda_96d01fe3721e46e4e8217a69a07d151b>' to 'main::<lambda_0d38919a9b2aba5caf910d83eac11776>' 
1>   No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 

智能感知,甚至想出了這個神祕的錯誤消息:

IntelliSense: more than one operator "?" matches these operands: 
     built-in operator "expression ? pointer : pointer" 
     built-in operator "expression ? pointer : pointer" 
     built-in operator "expression ? pointer : pointer" 
     built-in operator "expression ? pointer : pointer" 
     operand types are: lambda []bool()->bool : lambda []bool()->bool f:\Test\CppConsoleApplication\CppConsoleApplication.cpp 496 

而下面編譯

std::function<bool()> x = []() { return true; }; 

if (someCondition == false) 
    x = []() { return false; }; 

難道僅僅是VisualStudi之一o的錯誤,或者我在這裏做錯了什麼?

+0

VS2013沒有完全支持C++ 11功能。試試VS2015。您也可以嘗試將一個lambda放入函數指針中,以強制扣除常見類型。 –

回答

4

你的代碼很好,MSVC拒絕它是錯誤的。根據documentation

條件表達式E1的類型和值類別? E2:E3根據以下規則確定:
[1-4不適用]
5)否則,結果是一個prvalue。 如果E2和E3不具有相同類型,並且具有(可能是cv-qualified)類類型,則使用下面的內置候選項執行重載解析,以嘗試將操作數轉換爲內置類型。如果重載解析失敗,則該程序不合格。否則,所選擇的轉換被應用,並且轉換後的操作數,以代替原始操作數用於步驟6.

上述內置的候選者包括,試圖將兩個操作數轉換成指針的候選者。由於這兩個lambda都有一個空的捕獲列表,因此它們可以轉換爲bool(*)(),所以應該選擇這個候選人。 (其他候選人不適合,所以指針一個一點也不含糊。)

總結:

(someCondition == true) 
    ? []() { return true; } 
    : []() { return false; }; 

都應該lambda表達式轉換爲bool(*)()和產量的是,時調用指針到功能,與選定的lambda具有相同的效果。該指針不是懸空的,與lambda對象的生命週期無關。 (細節here。)
然後可以將得到的函數指針分配給std::function

請注意,具有空捕獲列表的兩個lambda都是至關重要的。如果其中一個lambda會捕獲某些內容,則轉換爲指針將不再有效,並且代碼將不合格。

您可以通過明確地將一個或兩個lambda表達爲bool(*)()std::function<bool()>來幫助您的舊MSVC。後者還允許您使用帶有非空捕獲列表的lambda表達式。(Live


爲了解釋診斷你的IDE爲您提供:

編譯器錯誤似乎從我鏈接列表步驟3)幹:它試圖一個操作數轉換成的類型另一個失敗。

智能感知似乎至少有正確的想法,並抱怨過載分辨率,如步驟5)所述。爲什麼它找到了太多我不知道的候選人。這是一個錯誤。