Assigning a volatile rvalue

若如初见. 提交于 2019-12-24 14:18:27

问题


I don't understand why the following code doesn't compile:

#include <iostream>

class Test {
public:
    Test() {
        std::cout << "Constructor" << std::endl;
    }
    Test(const Test&) {
        std::cout << "Copy Constructor" << std::endl;
    }

    Test& operator=(const Test&) {
        std::cout << "Assign Op" << std::endl;
        return *this;
    }

    Test& operator=(const volatile Test&) {
        std::cout << "Volatile Assign Op" << std::endl;
        return *this;
    }
};

volatile Test func() {
    Test a;
    return a;
}
int main() {
    Test b;
    volatile Test c;
    b = c; // this line is correct
    b = func(); // this line doesnt compile correct
    return 0;
}

the line:

    b = c; // this line is correct

While:

    b = func(); // this line doesn t compile

The compile complains about:

test.cc: In function ‘int main()’:
test.cc:31:14: error: no match for ‘operator=’ in ‘b = func()()’
test.cc:31:14: note: candidates are:
test.cc:12:11: note: Test& Test::operator=(const Test&)
test.cc:12:11: note:   no known conversion for argument 1 from ‘volatile Test’ to ‘const Test&’
test.cc:17:11: note: Test& Test::operator=(const volatile Test&)
test.cc:17:11: note:   no known conversion for argument 1 from ‘volatile Test’ to ‘const volatile Test&’

In the beginning I thought that it was due to constructor elision, which I was experimenting how to disable it using volatile, when I got into this situation. Compiling with:

-fno-elide-constructors

Didn't make any difference.

Any explanation for this? Testing with:

g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)


回答1:


Per [dcl.init.ref]/5, for a reference (i.e. the parameter of Test::operator=()) to be initialized by binding to an rvalue, the reference must be a const non-volatile lvalue reference, or an rvalue reference:

— Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference.

The line b = c; works because you are binding a reference (the parameter of Test::operator=()) to an lvalue.



来源:https://stackoverflow.com/questions/28048208/assigning-a-volatile-rvalue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!