我有以下类(class)(精简后只包含相关部分):
#include <string>
class Text
{
private:
std::string _text;
public:
Text(std::string&& text) :
_text(std::move(text))
{
}
operator const std::string&() const
{
return _text;
}
};
我的问题是:如果我想获得一个const std::string&
,我可以这样做而不会受到任何惩罚吗:
Text text("fred");
auto& s = static_cast<std::string>(text);
或者这会构造一个我最终得到引用的中间 std::string
吗?这种情况有标准的方法吗?我是 C++ 的新手。
最佳答案
不,当你调用 static_cast<std::string>(text)
时,您正在调用隐式定义的复制构造函数并创建一个临时对象。
但是,如果你要打电话
auto& s = static_cast<const std::string&>(text);
,那么您将正确调用显式转换运算符 operator const Noisy&()
.
让我们试试看
struct Noisy {
Noisy() { std::cout << "Default construct" << std::endl; }
Noisy(const Noisy&) { std::cout << "Copy construct" << std::endl; }
Noisy(Noisy&&) { std::cout << "Move construct" << std::endl; }
Noisy& operator=(const Noisy&) { std::cout << "C-assign" << std::endl; return *this; }
Noisy& operator=(Noisy&&) { std::cout << "M-assign" << std::endl; return *this; }
~Noisy() { std::cout << "Destructor" << std::endl; }
};
class Text {
public:
Text(Noisy&& text) : _text(std::move(text)) {}
operator const Noisy&() const { return _text; }
private:
Noisy _text;
};
测试 1
int main() {
Text text(Noisy{});
const auto& s = static_cast<Noisy>(text); // Needs 'const' to bind to temporary.
}
Default construct
Move construct
Destructor
Copy construct
Destructor
Destructor
测试 2
int main() {
Text text(Noisy{});
auto& s = static_cast<const Noisy&>(text);
}
Default construct
Move construct
Destructor
Destructor
注意:使用选项 -fno-elide-constructors
编译以避免复制省略优化。
关于c++ - 带有返回 const 引用的隐式转换运算符的类的 static_cast<> 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34829036/