当没有非常量运算符重载时,非常量对象将使用常量运算符
When there is no non-const operator overload, will non-const object use const operator?
>似乎在VS2013中。但是,为什么在有效的 c++ 第 3 项中,非常量运算符在执行完全相同的操作时调用 const 运算符?
这是有效 c++ 项 3 中的代码:
class TextBlock {
public:
...
const char& operator[](std::size_t position) const // same as before
{
...
...
...
return text[position];
}
char& operator[](std::size_t position) // now just calls const op[]
{
return const_cast<char&>( // cast away const on type;
static_cast<const TextBlock&>(*this)[position] // add const to *this's type;call const version of op[]
);
}
...
};
const
对象不能使用非const
方法。(请记住,运算符只是方法)。
但反之亦然:非const
对象可以使用const
方法(尽管如果存在,它将使用非const
等效方法)。
只有当方法被标记为const
时,它才会被const
:不允许编译器通过检查函数体来断言const
性。
是:如果存在const
成员函数,但没有非const
版本,则在非const
对象上调用该函数将使用const
函数。
#include <iostream>
struct Foo {
void bar() const { std::cout << "const bar()n"; }
};
int main() {
Foo f;
f.bar();
}
打印const bar()
.
请注意,反之则不然。不能在const
对象上调用非const
成员函数:
struct Foo {
void bar() { std::cout << "non-const bar()n"; }
};
int main() {
const Foo f;
f.bar();
}
给出编译器错误:
SO.cpp: In function 'int main()':
SO.cpp:9:11: error: passing 'const Foo' as 'this' argument of 'void Foo::bar()' discards qualifiers [-fpermissive]
f.bar();
^
EC++ 第 3 项"尽可能使用const
"有一个小节,避免const
和非const
成员函数中的重复。它建议你不要只让编译器选择const
版本的原因是返回类型不同(按const
) - 非const
版本会抛弃这一点:
class CharWrapper {
char c_;
public:
char const& getC() const
{
std::cout << "const getC()n";
return c_; // pretend this line is complicated
}
char& getC()
{
std::cout << "non-const getC()n";
char const& c = const_cast<CharWrapper const&>(*this).getC(); // call the right one to avoid duplicating the work
return const_cast<char&>(c); // fix the result type
}
};
int main() {
CharWrapper wrapper;
wrapper.getC() = 'a';
}
请注意,它调用 const 运算符并丢弃恒常性(它是少数不会导致 UB 的情况之一)。需要它,以便非常量运算符返回可变引用。否则,您将根本无法修改 vector 中包含的对象。
调用现有运算符而不是再次编写代码是为了避免代码重复和将来更改一个函数时可能出现的错误,但忘记了另一个函数。
关于您的评论:不涉及任何移动。它返回一个引用。我希望 const 和非 const 运算符的生成代码没有区别。
相关文章:
- 隐式常量/非常量运算符布尔
- 如何处理运算符=中的常量成员?
- 一种优雅或至少可行的方法,用于使用和接受具有重载方法和运算符的不同大小的文字数组常量
- 重载模板化类的[]运算符的常量版本
- 第二个常量在运算符函数中做什么?
- 如果可能的话,C++总是更喜欢右值引用转换运算符而不是常量左值引用吗?
- 如何为句柄类提供运算符 -> 的常量版本
- 如果类在 C++ 中具有常量或引用类型的非静态数据成员,为什么编译器不提供默认赋值运算符?
- 为什么类的赋值运算符的返回类型通常是非常量(而不是常量)引用?
- 引用模板类型的赋值运算符需要非常量重载
- 如何在 C++ 类中重载 'less than' 运算符以比较常量?
- 重载常量和非常量转换运算符返回数组类型时出现 MSVC 错误 C2593
- 为什么要在具有多个参数的重载运算符+中传递常量引用
- 字符和常量字符[2] 类型的操作数无效到二进制运算符
- 未找到采用常量类型的左操作数的'=='运算符
- C++ 重载运算符和常量
- 强制编译器选择常量运算符重载
- 当没有非常量运算符重载时,非常量对象将使用常量运算符
- 常量和非常量运算符重载
- std::string 的运算符 [] 和常量运算符 [] 之间的区别