[英]C++1y auto function type deduction
考慮以下:
auto list = std::make_tuple(1, 2, 3, 4);
/// Work like a charm
template <class T>
auto test1(T &&brush) -> decltype(std::get<0>( std::forward<T>(brush) )) {
return std::get<0>( std::forward<T>(brush) );
}
/// And now - C++14 feature
/// fail to compile - return value(temporary), instead of l-reference
template <class T>
auto test2(T &&brush) {
return std::get<0>( std::forward<T>(brush) );
}
int main()
{
auto &t1 = test1(list);
auto &t2 = test2(list);
}
http://coliru.stacked-crooked.com/a/816dea1a0ed3e9ee
兩者,gcc和clang拋出錯誤:
main.cpp:26:11: error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'
auto &t2 = test2(list);
^ ~~~~~~~~~~~
它不應該像decltype一樣工作嗎? 為什么不同?
更新
在std::get
情況下,不是這樣嗎? (我使用gcc 4.8)
template <class T>
auto&& test2(T &&brush) {
return std::get<0>( std::forward<T>(brush) );
}
auto
僅推斷對象類型,這意味着返回的對象的value-category不是返回類型的一部分。
使用auto
占位符,返回語句的類型由模板參數推導規則推導:
§ 7.1.6.4/7
auto specificer
[dcl.spec.auto]
如果占位符是自動類型指定者 ,則使用模板參數推導的規則確定推導的類型。
另一方面, decltype(auto)
使用del,如同decltype()
:
§ 7.1.6.4/7
auto specificer
[dcl.spec.auto]
如果占位符是
decltype(auto)
類型decltype(auto)
,則函數的聲明類型或函數的返回類型應僅為占位符。 根據7.1.6.2
中的7.1.6.2
確定為變量或返回類型推導出的類型,就好像初始化器是decltype
的操作數一樣。
因此,對於完美轉發返回類型,這是您應該使用的。 以下是它的外觀:
template <class T>
decltype(auto) test2(T &&brush) {
return std::get<0>(std::forward<T>(brush));
}
因此,返回類型將是rvalue / lvaue-reference,具體取決於推斷的brush
類型。
我在Coliru上測試了上面的內容,似乎g++ 4.8
還不能編譯上面的代碼,盡管使用clang++
它編譯得很好。
它不應該像decltype一樣工作嗎? 為什么不同?
它應該像decltype
一樣工作,但auto
在其他情況下不能像decltype
那樣工作,並且他們不想讓auto
不一致。
相反,C ++ 1y為慣用推導函數返回類型引入了新語法decltype(auto)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.