2010-03-11 71 views
11

我有這樣的代碼:的Visual Studio 2010和std ::功能

#include <iostream> 
#include <functional> 

struct A 
{ 
    int operator()(int i) const { 
     std::cout << "F: " << i << std::endl; 
     return i + 1; 
    } 
}; 

int main() 
{ 
    A a; 
    std::tr1::function<int(int)> f = std::tr1::ref(a); 
    std::cout << f(6) << std::endl; 
} 

目的是通過一個的reference_wrapper傳遞仿函數對象,在某種程度上避免無用的副本costructor電話。 我期待以下的輸出:

F: 6 
7 

它與GCC> = 4.4.0,Visual Studio 2008和通過與升壓替代的std :: TR1空間boost正常工作。它只適用於新的Visual Studio 2010 Express Beta 2和Release Candidate。

這個新的C++功能在vs2010中有bug嗎? 或者在代碼中存在一些錯誤或誤用?

+0

它不起作用? – UncleBens 2010-03-11 13:42:40

+0

@litb:我認爲OP在VS2010中使用'std :: tr1 :: ref'模板類和* not * boost存在問題。 – dirkgently 2010-03-11 13:47:44

+0

這裏是VS2010的構建輸出: http://pastebin.com/YQf4Qe8W – 2010-03-11 13:47:57

回答

11

我想我找到了原因。這就是TR1 3.4/2說約result_of<T(A1, A2, ..., AN)>::type,在返回類型的reference_wrapper<T>::operator()的確定中使用:

實現可以通過其產生表達式f的確切類型的任何裝置(T1,T2確定型部件, ...,tN)給定的類型。 [注:意圖是實現允許使用特殊的編譯器的鉤末端音符]

然後第3段:

如果F是不是由標準庫中定義的功能對象,並如果實現不能確定表達式f(t1,t2,...,tN)的類型或者表達式不合格,則實現應使用以下過程來確定類型成員:

  • 如果F是一個可能的cv資格類沒有memb呃名爲result_type或如果typename F::result_type不是一種類型:
    • 如果N = 0(無參數),則類型爲void。
    • 如果N> 0,類型爲typename F::template result<F(T1, T2,..., TN)>::type

該錯誤消息是試圖這些落式後背僞影。提供一個result_typeint的typedef,它應該工作,我想。請注意,在C++0x中,這是不同的。它不依賴於result_typeresult模板,因爲它可以使用decltype

如果與<functional>它在C++ 0x模式MSVC10失敗,它聞起來像一個錯誤,我會說。但也許別人知道發生了什麼。它可能(但不能保證)以<tr1/functional>在C++ 0x模式下工作,如果該頭選擇decltype而不是::result_type。我會打印- 這樣我認爲無論是使用tr1標頭還是c++0x標頭,它都應該始終有效。


還要注意boost::tr1說,它的文檔,它不支持函數調用操作中(但它僅僅支持隱式轉換爲T&)。

+1

是的,這個修復了這個問題:D 這是一個對於2008年之前版本的迴歸,vs2010相當遺憾......最近的草案嚴格要求編譯器能夠自動識別返回類型 http://www.open-std.org/JTC1/SC22/ WG21/docs/papers/2009/n3000.pdf 第20.7.4 – 2010-03-11 14:57:17