在cpprefernce部分:值类别中,它声明"对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员"是xvalue.在标准(我发现于:N4140,草案C++ 14标准)中,它声明(在第87页)"如果表达式是......一个指定非静态数据成员的类成员访问表达式,则表达式是xvalue对象表达式为xvalue的非引用类型."
我想通过以下代码检查我对此的理解:
struct B { // B for Boring...
int i{0};
};
template <typename T> struct V {
V() { cout << "V" << endl; }
};
template <typename T> struct V<T &> { // Partial Specialization
V() { cout << "V&" << endl; }
};
template <typename T> struct V<T &&> { // Partial Specialization
V() { cout << "V&&" << endl; }
};
int main() {
int i{1};
V<decltype((1))> v1; // V
V<decltype((i))> …Run Code Online (Sandbox Code Playgroud) 根据关于复制赋值运算符的 C++ 参考:
如果以下任何一项为真,则类 T 的默认复制赋值运算符被定义为已删除
T 有一个非类类型(或其数组)的非静态数据成员,它是 const ...
我希望创建一个案例,其中我有一个 const 类类型的数据成员和一个未定义为已删除的默认复制赋值运算符。在这样做时,我发现了 clang 和 gcc 之间的差异。考虑以下代码:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
Run Code Online (Sandbox Code Playgroud)
当我编译它时,g++ -std=c++14我收到以下错误:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
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