在完美转发中,std::forward用于转换命名的右值引用t1和t2未命名的右值引用.这样做的目的是什么?inner如果我们离开t1&t2作为左值,那将如何影响被调用的函数?
template <typename T1, typename T2>
void outer(T1&& t1, T2&& t2)
{
inner(std::forward<T1>(t1), std::forward<T2>(t2));
}
Run Code Online (Sandbox Code Playgroud) 在以下场景中
template <class T>
? f(T&& a, T&& b)
{
return a > b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
最佳回报类型是什么?到目前为止我的想法是:
返回r值refs,完美转发函数参数:
template <class T>
decltype(auto) f(T&& a, T&& b)
{
return a > b ? forward<T>(a) : forward<T>(b);
}
Run Code Online (Sandbox Code Playgroud)移动构造返回值:
template <class T>
auto f(T&& a, T&& b)
{
return a > b ? forward<T>(a) : forward<T>(b);
}
Run Code Online (Sandbox Code Playgroud)尝试找到一种方法来启用(N)RVO(即使我认为因为我想使用不可能的函数参数)
这些解决方案有问题吗?还有更好的吗?什么是最佳做法?
请考虑以下代码:
int x;
int& f() {
return x ? x : throw 0;
}
Run Code Online (Sandbox Code Playgroud)
随着gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)我得到以下编译错误:
cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
Run Code Online (Sandbox Code Playgroud)
请注意,这在clang中编译得很好.以下是(我相信的)标准中的相关陈述:
N4659 [8.16.2.1](条件运算符):
第二个或第三个操作数(但不是两个)是一个(可能带括号的)throw-expression(8.17); 结果是另一个的类型和值类别.
据我所知,x是一个左值,所以在我看来clang是对的.我错了吗?
c++ g++ conditional-operator language-lawyer value-categories