C++ 返回转发的引用

C++ 返回转发的引用,c++,c++11,C++,C++11,我想构建一个最大值函数,将较大的值转发给结果,保持引用的类型(右值或左值) #包括 模板 constexpr T&&mmax(T&&left,T&&right){ 返回左>右?标准::前进(左):标准::前进(右); } int main(){ mmax(1,2); } 然而,这给了我 max.cc: In instantiation of 'constexpr T&& mmax(T&&, T&&) [with T = int]': max.cc

我想构建一个最大值函数,将较大的值转发给结果,保持引用的类型(右值或左值)

#包括
模板
constexpr T&&mmax(T&&left,T&&right){
返回左>右?标准::前进(左):标准::前进(右);
}
int main(){
mmax(1,2);
}
然而,这给了我

max.cc: In instantiation of 'constexpr T&& mmax(T&&, T&&) [with T = int]':
max.cc:9:14:   required from here
max.cc:5:72: warning: returning reference to temporary [-Wreturn-local-addr]
     return left > right ? std::forward<T>(left) : std::forward<T>(right);
max.cc:constexpr T&&mmax(T&&,T&&)[with T=int]的实例化:
最大抄送时间:9:14:此处需要
max.cc:5:72:警告:返回对临时[-Wreturn local addr]的引用
返回左>右?标准::前进(左):标准::前进(右);
为什么呢?我正在使用GCC4.8.2和-std=c++11


< > >强>编辑< /强>:这不发生在CLAN+++ .< /P> < P>您的原始代码应该工作,因为C++ 11 5.16/4中的条件运算符的规则:

如果第二个和第三个操作数是相同值类别的glvalues,并且具有相同的类型,则结果属于该类型和值类别

两个表达式
forward(left)
forward(right)
要么都是左值,要么都是x值,因此它们总是glvalues,并且它们都是
T
类型,因此规则适用,条件表达式的类型应该是相同的类型和值类别

但是,作为潜在编译器错误的解决方法,您可以使用以下表达式,这样可以避免计算条件表达式的类型和值类别(这似乎是错误所在):

返回std::forward(左>右?左:右);

return std::forward(左>右?左:右)怎么样?你在用什么编译器?我没有使用Apple LLVM 5.0发出此警告。无论如何,这很奇怪-你不能真正拥有多个参数的通用参考。@kerreksb当然可以,它只是没有那么有用@trion:推断一个参数并强制另一个参数具有相同类型的标准方法是使第二个类型不可推断,如:
template void foo(T&&a1,typename std::common_type::type a2)
现在
a1
受通用引用约束,而
a2
必须能够与之匹配。上面的危险是,如果转换完成,您现在会以静默方式将引用返回给临时用户。考虑返回<代码> t>代码>如果你使用了<代码> T&&<代码>,它也能使引用生存期延长。我们知道,
都是参照物,所以不应该有临时的,但谁知道呢?@Kerrek:为什么不能有临时的呢?只有非常量左值引用不会绑定到临时值,并且此函数同时接受常量左值引用和右值引用。@BenVoigt:但这些不是由函数创建的临时值。它们是调用方的责任。检查
auto&&x=mmax(exp1,exp2)如果exp1或exp2是临时性的,那么事情就糟糕了。您很少希望返回
T&
-返回
T
,事情就会进展顺利。
max.cc: In instantiation of 'constexpr T&& mmax(T&&, T&&) [with T = int]':
max.cc:9:14:   required from here
max.cc:5:72: warning: returning reference to temporary [-Wreturn-local-addr]
     return left > right ? std::forward<T>(left) : std::forward<T>(right);
return std::forward<T>(left > right ? left : right);