在不同的运算符=重载之间,编译似乎没有遵循正确的路径

Compilation seems not to follow the correct path among different operator= overloads

本文关键字:路径 编译 运算符 重载 之间      更新时间:2023-10-16

我有两个矩阵类,一个用于CPU,另一个用于GPU,分别为MatrixCudaMatrix。声明和定义位于文件.h.cpp.cuh.cu中。在main中,我有

Matrix<int2_>      foo1(1,2);
// Definition of the elements of foo1...
CudaMatrix<int2_>  foo2(1,2);
cout << typeid(foo1).name() << "n";
cout << typeid(foo2).name() << "n";
// Equality
foo2=foo1;

现在,我在CudaMatrixMatrix之间没有operator=过载,但我有下面的operator=过载

const CudaMatrix& operator=(const CudaMatrix<LibraryNameSpace::int2_>&);

在两个CCD_ 12之间。发生的情况如下:

  1. 两个typeid返回foo1foo2的正确类
  2. 上面的operator=重载是在运行时为foo2=foo1赋值而编译和调用的。相反,我本以为会出现汇编错误
  3. 赋值的结果导致foo2正确结果

我正在使用Visual Studio 2010,并在发布模式下进行编译。

有人知道为什么会出现这种明显不合逻辑的行为吗?

谢谢。

它们之所以能起作用,关键是因为您同时拥有复制构造函数和显式复制赋值运算符。这两件事加在一起,使一个看似未定义的case正确发挥作用。所以当你这样做的时候:

Matrix<int2_>      foo1(1,2);
CudaMatrix<int2_>  foo2(1,2);
foo2 = foo1;

发生的情况与此相当:

Matrix<int2_>      foo1(1,2);
CudaMatrix<int2_>  foo2(1,2);
// foo2 = foo1;
{   
    CudaMatrix<int2_> x(foo1); // copy constructor
    foo2 = x; // Copy assignment
}

请注意,在这里,您应该注意设备内存使用的影响(即,两个设备内存分配和两组您拥有的API调用)。

值得指出的是,这不是CUDA特有的,它是C++98对象模型的标准特性。如果你想了解更多关于这是如何以及为什么工作的(以及为什么看似类似的反例不起作用),你可能会从修改三条规则中受益。