2015-02-10 64 views
13

我有一些代碼在VS2015下失敗,但在GCC下工作。我很確定這個錯誤是在Visual Studio中,但是要確保我對decltype(auto)的理解是正確的。析構函數臨時調用應該超出範圍

#include <iostream> 
using namespace std; 

string zero_params() 
{ 
    return "zero_params called."; 
} 

template< typename F > 
auto test1(F f) -> decltype(auto) 
{ 
    return f(); 
} 

int main() { 
    cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl; 
    cout << test1(zero_params) << endl; 

    cout << "Done!" << endl; 
    return 0; 
} 

在Visual Studio下,由zero_params返回的字符串被推斷爲右值引用。此外,該對象的析構函數在test1()內調用f的返回(這似乎是一個合理的地方,可以破壞對象)。

在GCC下,返回的字符串不會被推斷爲右值引用。正如我所料,析構函數在cout語句中使用後調用。

在Visual Studio下指定返回類型爲'string'而不是decltype(auto)修復它,就像在test1中返回f()時使用remove_reference_t一樣。

我預計將是GCC是正確的,因爲對於zero_params)函數簽名(是串,不串& &所以我希望非參照「冒泡」到TEST1的返回類型,如果它使用decltype (汽車)。

這是一個正確的評估?


LATE編輯:

我發現來解決這個問題與VS2015另一種方法是給包裹在一個lambda來測試1功能:

cout << test1(zero_params) << endl; 

到:

cout << test1([](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); }) << endl; 
+5

對,'f()'是一個prvalue,所以'decltype'應該推斷'std :: string'而不是'std :: string &&'。 – 2015-02-10 19:43:19

+3

請在[MS Connect](https://connect.microsoft.com/VisualStudio/)上提交錯誤報告,並在此處發佈鏈接。這個_really_需要在VS2015進入RTM之前解決,如果'decltype(auto)'意圖不是無用的...... – ildjarn 2015-02-10 21:19:16

+0

不幸的是MS Connect告訴我,我沒有權限提交錯誤報告。然而,在Visual Studio中,我已經做了下一個最好的事情 - 使用他們的'皺眉臉'提交反饋,包括測試代碼的屏幕截圖和描述。不幸的是,我不認爲這種方法是可追蹤的?希望有人將它傳遞到正確的部門 – qeadz 2015-02-10 21:46:43

回答

2

所以based on the comments我們可以得出結論:

的錯誤是:

  • 編譯器應該推斷返回類型爲字符串
  • 它實際上推斷它是字符串& &
  • 因此,它破壞了價值過早

的解決方法是:

  • 不要使用該函數的返回類型
  • 包裝在一個lambda表達式功能才通過decltype(自動)它在
+0

我們能否將這些意見集成到此答案中?評論是暫時的。 – 2015-02-13 22:45:54

+1

https://connect.microsoft.com/VisualStudio/feedback/details/1124457/decltype-auto-deducing-wrong-type-in​​-some-cases – 2015-02-15 03:18:24