1

我正在编写一些函数来操作矢量数据。

我定义了不可复制的对象(私有复制构造函数和赋值运算符)。

然后我定义了模板化运算符 =

template <typename G>
inline const TMatrix &operator=(const G &gen) {
    ir_mat::Copy<G, Dimension>::start(m_data, gen);
    return *this;
}

以及一些额外的运算符,如 '+'、'*',如本文所述

现在我可以将表达式的结果分配给一个对象:

Vector3f v1, v2, v3;
v1 = v2 + v3;

为什么我不能声明一个变量并在单个语句中分配它?

Vector3f v1, v2;
Vector3f v3 = v1 + v2;

是不是因为这个赋值试图在实例化变量之前创建一个临时对象,然后将它复制到新对象中?我可以使用我的运算符“=”来实例化新对象,而无需临时存储吗?我必须为此定义一个特殊的构造函数吗?

更新

我还定义了一个模板化的复制构造函数(可能是最简单的形式):

template <typename G>
TMatrix(const G &data) {
    operator=(data);
}

现在我也可以将 v3 实例化为:

Vector3f v3(v1 + v2);

但是其他任务仍然没有运气:

Vector3f v3 = v1 + v2;
4

2 回答 2

3

这个初始化:

 Vector v3(v1 + v2);

将调用您漂亮的模板化构造函数。

这个初始化:

 Vector v3 = v1 + v2;

最终被翻译成这样:

 Vector v3(Vector(v1 + v2));

本质上,编译器尝试使用复制构造函数,并尝试找出如何将初始化程序转换为适当的类型。

选择创建一个可从随机类型中分配但不能复制分配或复制构造的类型是一个非常奇怪的选择。我看到我的假设是你这样做是为了避免临时工是正确的。除了你不这样做是因为临时变量确实很昂贵,而是因为你想构建一个稍后将被评估的表达式。大概是因为您想矢量化复杂的表达式评估。

是的,您将无法使用初始化的赋值形式。至少,我想不出办法让它发挥作用。

我的建议是以某种方式转变Vector为您正在构建的表达式的句柄。该句柄可以是作为输入的真实向量的句柄。或者它可能是 VectorExpression 的句柄,它是对向量进行操作的结果。

如果您不想共享拥有句柄的对象的所有权,您仍然无法实现复制分配或复制构造。但在 C++11 中,您仍然可以实现句柄的移动构造和移动分配。

于 2013-02-11T14:49:29.710 回答
3

使用初始化语法初始化类类型的对象=不使用operator=,它使用复制构造函数。也就是说,Vector3f v3 = v1 + v2;与 相同Vector3f v3(v1 + v2);。如果您的复制构造函数不可访问,您将无法执行此操作。

operator=只在已经构造的对象上调用(如v1 = v2 + v3),形式T& operator=(const T&)称为复制赋值

于 2013-02-11T14:39:54.140 回答