Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:强制转换运算符重载和引用_C++_Casting_Reference_Operator Overloading - Fatal编程技术网

C++ C++;:强制转换运算符重载和引用

C++ C++;:强制转换运算符重载和引用,c++,casting,reference,operator-overloading,C++,Casting,Reference,Operator Overloading,C++允许通过创建一个操作符T()来重载类型转换,其中T是我们要转换的类型 现在,该功能如何与引用一起使用?例如: struct Y{ int i; }; struct X{ Y y; operator Y() const { return y; } }; 在这里,我们可以将X强制转换为Y,只需返回包含的Y。但是如果我们想对Y引用进行转换,该怎么办呢。例如,C++允许我们这样做: struct X{ Y y; operator Y&(){ retu

C++允许通过创建一个
操作符T()
来重载类型转换,其中
T
是我们要转换的类型

现在,该功能如何与引用一起使用?例如:

struct Y{ int i; };

struct X{
    Y y;

    operator Y() const { return y; }
};
在这里,我们可以将
X
强制转换为
Y
,只需返回包含的
Y
。但是如果我们想对
Y
引用进行转换,该怎么办呢。例如,C++允许我们这样做:

struct X{
    Y y;

    operator Y&(){ return y; }
    operator const Y&() const { return y; }
};
现在,我们可以将
X
强制转换为
Y
引用或
const
引用(这也适用于
const X

第一个例子和第二个例子的语义有什么不同吗?如果我想允许对引用进行强制转换,最好的方法是什么?

我可以想象,即使我写了代码>操作符To(),没有任何代码>和代码>,C++也可以允许强制引用返回一个结果(也就是说,当我指定<代码>操作符T-())/>代码>时,它可能不知何故添加隐式<代码>操作符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
}
intmain(){
X;
Y&Y=x;//Y现在引用x中的Y
y、 i=5;
标准::cout
声明
运算符T()
是否意味着强制转换总是按值返回
T

转换运算符的返回类型隐式地正是它们转换为的类型

[…]转换函数的类型为“不带参数的函数返回转换类型id”

§12.3.2[类别转换功能]

用叮当声++:

#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;
}
#包括
课堂测试
{
公众:
测试(int n):nb{n}{}
公众:
运算符int(){return nb;}
私人:
int nb;
};
内部主(空)
{
测试t{42};
int x=t;
int&ref=t;//错误:对类型“int”的非常量左值引用无法绑定到不相关类型“test”的值
int&&rref=t;//编译很好

std::cout声明
运算符T()
是否意味着强制转换总是按值返回
T

这意味着转换运算符将返回
T
指定的值。可以是引用、指针或值。例如,给定某种类型(根据OP)
Y

operator Y();
operator Y&();
operator Y*();
所有(带有cv限定变体)的有效用户定义转换。若要使用
Y
作为参考,您需要将其作为参考返回

因此,是的,转换为非引用的
T
意味着返回类型是一个值。这与返回的-a值是内联的

第一个示例和第二个示例的语义有什么不同吗?

是的,存在语义差异。它们的语义差异与其他引用和值返回类型的方法相同。它们的不同之处与以下两种方法的不同之处相同

Y get_y_value();
Y& get_y_ref();
注释

在同一个类中混合使用
运算符Y();
运算符Y&();
可能会导致不明确的重载(至少clang对此表示不满,但gcc似乎乐于将两者混合使用)


我不想知道在这里,哪一种方法更好,因为你的情况的细节还不清楚。一般来说,当实现用户定义的转换时,总是考虑如何执行通常的转换,并且经常会返回rValue.随着C++ 11的出现,他们也倾向于使用<代码>显式< /代码>;出于同样的原因,构造函数是显式的

(如果特别需要,也可以不显式)。

您是在询问返回值和引用之间的语义差异,还是返回常量引用和非常量引用之间的语义差异?@无用:我是在问:是否声明
运算符T()
(不带
&
)暗示强制转换总是按值返回
T
?或者在某些情况下有一些规则可以作为参考返回
T
?我试图澄清这个问题。谢谢!但是如果我声明下面的示例(使用
T&
const T&
),那么我是否可以省略
T
cast,因为reference+const reference总是可以使用的?是的,因为:“返回“reference to cv2 X”的转换函数根据引用类型返回“cv2 X”类型的左值或X值,因此在选择候选函数的过程中被视为产生X。”§13.3.1.5[over.match.conv]@gexicide:如果通过参考版本提供,您几乎肯定希望省略
T
版本,否则您将需要客户端代码手动消除大量客户端使用的歧义(即显式编写
x.operator Y()
x.operator Y&()
).如果是C++11,则返回
Y
的对该重载的右值引用是明智的@tonyd@Yakk:有时-有时返回的
Y
可能会立即用作表达式的一部分,并且不会绑定任何引用,或者可能会被引用以进行计算,但不会从中复制……是的,我想让人们修改memb呃。但是,我不知道它是否是一个昂贵的副本,因为它的类型是一个模板参数,所以它可以依赖。我只是想给客户端最高的灵活性。那么什么是最佳的强制转换操作符集?(“intx”应该是“intx”。。除此之外)没有人提到隐式cast运算符重载不是很好的样式?只提供模板setter和getter(一个重载用于值复制,一个重载用于l引用,一个重载用于r引用)怎么样@gexicide您的第二个选择,引用和const引用转换标记为const。@DarioOO好吧,这取决于您想要实现什么,cast运算符比简单的getter/setter具有更强的语义,它基本上意味着您的类型足够兼容,因此可以将一个转换为另一个。隐式转换在某些ca中很有意义虽然它可以成为