C++ 从C++;14
是否有任何理由再使用以下语法:C++ 从C++;14,c++,c++14,trailing-return-type,return-type-deduction,C++,C++14,Trailing Return Type,Return Type Deduction,是否有任何理由再使用以下语法: template<typename T> auto access(T& t, int i) -> decltype(t[i]) { return t[i]; } 模板 自动访问(T&T、int i) ->decltype(t[i]) { 返回t[i]; } 现在我们可以使用: template<typename T> decltype(auto) access(T& t, int i) { re
template<typename T>
auto access(T& t, int i)
-> decltype(t[i])
{
return t[i];
}
模板
自动访问(T&T、int i)
->decltype(t[i])
{
返回t[i];
}
现在我们可以使用:
template<typename T>
decltype(auto) access(T& t, int i)
{
return t[i];
}
模板
decltype(自动)访问(T&T,int i)
{
返回t[i];
}
后面的返回类型语法现在似乎有点多余了?是的,至少有三个原因:
T[i]
,因此您会得到类型约束或主体返回的内容到您想要得到的内容的转换还有第四个原因。推断的回报类型不利于SFINAE。如果
t[i]
无效,此重载将直接从重载集中退出:
template<typename T>
auto access(T& t, int i)
-> decltype(t[i])
{
return t[i];
}
尾部返回类型允许您精确指定要返回的表达式类型:
template <typename T>
auto foo(T const& val)
-> decltype(val.some_function_returning_an_optional())
{
if (val.is_invalid()) return std::nullopt;
return val.some_function_returning_an_optional();
}
也许只是我,但我有时想看看函数定义,并立即知道它会返回什么,而不只是看实现,你不是唯一的一个,C++编译器经常也喜欢这样。他们很容易与新标准特性的早期实现混淆。(或者更确切地说:编译器A在编译器B理解的代码上出错,反之亦然……)第二个示例并不好,因为您可以只执行正常的前导返回类型。我觉得只剩下sfinae表达式了。@NirFriedman这是一个简化的例子,但我遇到了一个例子,它救了我。返回类型取决于参数,但它也是可选的。可以使用前导返回类型,但一点也不好。我将改进第二个示例好吧,当我们有了概念并彻底使用它们时,返回类型推断将有一个上升趋势,因为我们让SFINAE通过了它。它可能只需要几十年的时间。@重复数据消除,或者可能取决于具体情况。对于特殊约束,
->decltype(t[i])
比要求的(t const&v,int i){v[i];}
短得多。但如果某些约束使用得足够多,它们可能会转化为命名的概念,这将很好地工作。
#include <optional> // C++17 standard library feature
template <typename T>
auto foo(T const& val)
{
if (val.is_invalid()) return std::nullopt;
return val.some_function_returning_an_optional();
}
template <typename T>
auto foo(T const& val)
-> decltype(val.some_function_returning_an_optional())
{
if (val.is_invalid()) return std::nullopt;
return val.some_function_returning_an_optional();
}
template <typename T>
decltype(std::declval<T const&>().some_function_returning_an_optional())
foo(T const& val)
{
if (val.is_invalid()) return std::nullopt;
return val.some_function_returning_an_optional();
}