static_cast 去除常量
static_cast taking away constness
据我所知(以及本主题:When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?)const_cast
是唯一应该能够消除变量常量性的转换。但是,当弄乱 clang-6.0
和 g++5.4.0
时,我偶然发现了一种与上述相矛盾的行为。似乎 static_cast
做的完全一样。
这些主要函数在两个编译器中给出完全相同的结果:
测试class定义
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;
};
和const_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
const_cast<Base&>(b).no_const();
std::cout << "END\n";
}
和static_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
static_cast<Base>(b).no_const();
std::cout << "END\n";
}
结果:
BEGIN
Base::Base()
Base::no_const()
END
什么给了?
为 Base
添加复制构造函数定义,它将回答您的问题。
Base(Base const&) {
std::cout << "Base::Base(Base const&)\n";
}
第二个示例的输出更改为
BEGIN
Base::Base()
Base::Base(Base const&)
Base::no_const()
END
尝试从 b
自身中摆脱 constness,您将看到一个错误
static_cast<Base&>(b).no_const();
// ^
error: invalid static_cast
from type 'const Base
' to type 'Base&
'
static_cast<Base&>(b).no_const();
据我所知(以及本主题:When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?)const_cast
是唯一应该能够消除变量常量性的转换。但是,当弄乱 clang-6.0
和 g++5.4.0
时,我偶然发现了一种与上述相矛盾的行为。似乎 static_cast
做的完全一样。
这些主要函数在两个编译器中给出完全相同的结果:
测试class定义
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;
};
和const_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
const_cast<Base&>(b).no_const();
std::cout << "END\n";
}
和static_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
static_cast<Base>(b).no_const();
std::cout << "END\n";
}
结果:
BEGIN
Base::Base()
Base::no_const()
END
什么给了?
为 Base
添加复制构造函数定义,它将回答您的问题。
Base(Base const&) {
std::cout << "Base::Base(Base const&)\n";
}
第二个示例的输出更改为
BEGIN
Base::Base()
Base::Base(Base const&)
Base::no_const()
END
尝试从 b
自身中摆脱 constness,您将看到一个错误
static_cast<Base&>(b).no_const();
// ^
error: invalid
static_cast
from type 'const Base
' to type 'Base&
'static_cast<Base&>(b).no_const();