以下定义了一个min函数
template <typename T, typename U>
constexpr auto
min(T&& t, U&& u) -> decltype(t < u ? t : u)
{
return t < u ? t : u;
}
Run Code Online (Sandbox Code Playgroud)
有一个问题:它似乎写得完全合法
min(10, 20) = 0;
Run Code Online (Sandbox Code Playgroud)
这已经过Clang 3.5和g ++ 4.9的测试.
解决方案很简单,只是std::forward用来恢复参数的"rvalue-ness",即修改正文和decltype说
t < u ? std::forward<T>(t) : std::forward<U>(u)
Run Code Online (Sandbox Code Playgroud)
但是,我无法解释为什么第一个定义不会产生错误.
鉴于我的转发和普遍引用,两者的理解t和u演绎他们的论据类型,int&&当传递整数常量.但是,在正文中min,参数有名称,因此它们是左值.现在,条件运算符的真正复杂规则发挥作用,但我认为相关的是:
- E2 [和] E3都是相同类型的glvalues.在这种情况下,结果具有相同的类型和值类别.
因此,返回类型operator?:应该是int&&为好,应该不是吗?但是,(据我所知),Clang和g ++都 …
c++ conditional-operator rvalue-reference c++11 universal-reference
我有 :
#include<stdio.h>
int main()
{
int a=5,b=6;
(a>b)?b=a:b=b; // Here is the error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但如果我更换:
(a>b)?b=a:b=b; // Error
with
(a>b)?(b=a):(b=b); // No-Error
Run Code Online (Sandbox Code Playgroud)
我理解这lvalue是一个可以分配某些东西的价值,它与它有什么不同rvalue,但为什么会extra parenthesis产生不同.
假设我们有一个带有 2 个 xvalue 操作数的三元运算符。
struct A {
A() { std::cout<<"A ctor"<<std::endl; }
~A() { std::cout<<"A dtor"<<std::endl; }
A(A const&) { std::cout<<"A copy ctor"<<std::endl; }
A(A&&) { std::cout<<"A move ctor"<<std::endl; }
void foo() & { std::cout<<"A&.foo()"<<std::endl; }
void foo() const& { std::cout<<"A const&.foo()"<<std::endl; }
void foo() && { std::cout<<"A&&.foo()"<<std::endl; }
void foo() const&& { std::cout<<"A const&&.foo()"<<std::endl; }
};
int main()
{
A a;
A a2;
(true? static_cast<A&&>(a) : static_cast<A&&>(a2)).foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据cppreference条件运算符
4) 如果 E2 和 E3 是相同类型和相同值类别的左值,则结果具有相同类型和值类别,并且如果 E2 …