编译似乎不遵循不同operator =重载之间的正确路径

时间:2013-06-25 10:10:52

标签: c++ class cuda operator-overloading

我有两个矩阵类,一个用于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;

现在,operator=CudaMatrix之间没有Matrix重载,但我有以下operator=重载

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

两个CudaMatrix之间。会发生以下情况:

  1. 两个typeid会返回foo1foo2的正确类;
  2. 上述operator=重载在运行时编译并调用foo2=foo1赋值。相反,我原本期望编译错误;
  3. 分配结果会导致foo2正确结果!
  4. 我正在使用Visual Studio 2010并在发布模式下进行编译。

    任何人都有一些暗示为什么会发生这种明显不合逻辑的行为?

    感谢。

1 个答案:

答案 0 :(得分:2)

它们解决这个问题的关键因为你有一个复制构造函数和一个显式复制赋值运算符。将这两件事放在一起,使看似未定义的案例正确起作用。所以当你这样做时:

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对象模型的标准功能。如果您想了解更多有关其工作原理和原因(以及为什么看似类似的反例不起作用),您可能会受益于修改rule of three