gex*_*ide 9 c++ casting reference operator-overloading
C++允许通过创建一个operator T()where T我们想要转换为的类型来重载类型转换.
现在,此功能如何与引用一起使用?例如:
struct Y{ int i; };
struct X{
Y y;
operator Y() const { return y; }
};
Run Code Online (Sandbox Code Playgroud)
在这里,我们可以强制X转换Y包含的内容Y.但是,如果我们想要对某个Y参考进行强制转换呢?例如,C++允许我们这样做:
struct X{
Y y;
operator Y&(){ return y; }
operator const Y&() const { return y; }
};
Run Code Online (Sandbox Code Playgroud)
现在,我们可以X转换为Y引用或const引用(也适用于a const X).
第一个和第二个例子的语义有什么不同吗?如果我想允许转换为引用,最好的方法是什么?
我可以想象,即使我operator T()没有任何写入&,C++可能允许转换通过引用返回结果(即,operator T&()当我指定时它可能以某种方式添加隐式方法operator T()).
例如,我想要以下代码工作:
int main(){
X x;
Y& y = x; // y now references the y inside x
y.i = 5;
std::cout << x.y.i << std::endl; // Should print 5 now
}
Run Code Online (Sandbox Code Playgroud)
实现这一目标的最简单方法是什么?
声明 a 是否意味着operator T()强制转换总是T按值返回 a ?
这意味着转换运算符将按 指定的方式返回T。无论是引用、指针还是值。例如,给定某种类型(根据OP)Y:
operator Y();
operator Y&();
operator Y*();
Run Code Online (Sandbox Code Playgroud)
是否所有(带有 cv 限定的变体)有效的用户定义的转换。要用作Y参考,您需要将其作为参考返回。
所以,是的,转换为T不是引用的 a 意味着返回类型是一个值。这与一般的转换语义一致- 返回一个值。
第一个和第二个例子的语义有什么不同吗?
是的,存在语义差异。它们与具有引用与值返回类型的其他方法具有相同的语义差异。它们的不同之处就像以下两种方法的不同一样;
Y get_y_value();
Y& get_y_ref();
Run Code Online (Sandbox Code Playgroud)
笔记
在同一个类中混合operator Y();和operator Y&();可能会导致不明确的重载(至少 clang 抱怨这一点,但 gcc 似乎很乐意将两者混合)。
我不会在这里就哪一个更好发表意见,因为您的情况细节尚不清楚。但一般来说,在实现用户定义的转换时,请始终考虑通常如何执行强制转换以及可能更频繁地返回右值。explicit随着 C++11 的出现,也支持它们;出于同样的原因,构造函数是explicit(或者如果特别需要则不是)。
是否声明
operator T()演员总是返回一个T值?
是.
返回类型的转换运算符隐式正是它们转换为的内容.
[...]转换函数的类型是"不返回convert-type-id的参数的函数".
§12.3.2[class.conv.fct]
使用铿锵++:
#include <iostream>
class test
{
public:
test(int n) : nb{n} {}
public:
operator int() { return nb; }
private:
int nb;
};
int main(void)
{
test t{42};
int x = t;
int& ref = t; // error: non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'test'
int&& rref = t; // compiles fine
std::cout << x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这表明您确实返回了一个临时的新值。
帮助您在两种情况之间进行选择的真正问题是:您是否想让人们修改您的内部成员(返回引用)以及该成员的复制成本是否昂贵(使用 const 引用而不是值)?