static_cast带走了constness

Leś*_*ajs 4 c++

根据我的知识(以及这个主题:什么时候应该使用static_cast,dynamic_cast,const_cast和reinterpret_cast?)const_cast是唯一应该能够取消变量constness的转换.然而,当我搞砸了clang-6.0,g++5.4.0我偶然发现了一个与上述相反的行为.看起来static_cast完全一样.

这些主要功能与两个编译器提供完全相同的结果:

测试类定义

struct Base {
        Base() {
                std::cout << "Base::Base()\n";
        }
        void test() const {
                std::cout << "Base::test()\n";
        }

        void no_const() {
                std::cout << "Base::no_const()\n";
        }

        virtual ~Base() = default;
};
Run Code Online (Sandbox Code Playgroud)

const_cast

int main(void) {
        std::cout << "BEGIN\n";
        const Base b;
        const_cast<Base&>(b).no_const();

        std::cout << "END\n";
}
Run Code Online (Sandbox Code Playgroud)

static_cast

int main(void) {
        std::cout << "BEGIN\n";
        const Base b;
        static_cast<Base>(b).no_const();

        std::cout << "END\n";
}
Run Code Online (Sandbox Code Playgroud)

结果:

BEGIN
Base::Base()
Base::no_const()
END
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?

Pra*_*ian 5

添加复制构造函数定义Base,它将回答您的问题.

Base(Base const&) {
        std::cout << "Base::Base(Base const&)\n";
}
Run Code Online (Sandbox Code Playgroud)

第二个示例的输出更改为

BEGIN
Base::Base()
Base::Base(Base const&)
Base::no_const()
END
Run Code Online (Sandbox Code Playgroud)

现场演示


尝试从b自身中抛弃constness ,你会看到一个错误

static_cast<Base&>(b).no_const();
//              ^
Run Code Online (Sandbox Code Playgroud)

错误:static_cast从' const Base'键入' Base&' 类型无效

  static_cast<Base&>(b).no_const();
Run Code Online (Sandbox Code Playgroud)