我有这门课:
class A
{
public:
//copy and move constructor,operator=
A func(const A& a,const A& b)
{
A c;
//do some stuff...
return c;
}
};
当我以这种方式使用它时它工作正常:
A a;
A b;
A c=func(a,b);
但问题是当我以这种方式使用它时:
A a;
A b;
a=func(a,b);
它做了一些不必要的事情(制作 c 并在我的类中调用构造函数非常耗时!)
我想知道 a 是否等于传递给函数的变量之一,然后我不创建 c 并就地执行操作
经过一段时间的思考,我想到了这个解决方案:
class A
{
public:
//copy and move constructor and operator=
A func(const A& a,const A& b)
{
A c;
//do some stuff...
return c;
}
A func(const A& a,const A& b,bool inPlace)
{
if(!inPlace)
return func(a,b);
else
{
//const-cast a then do stuff on a
return a;
}
}
};
现在可以正常工作了:
A a;
A b;
A c=func(a,b);
a=func(a,b,true);
但它仍然不适用于:
A a;
A b;
b=func(a,b,true);
因此需要对 func
进行另一个重载。
但这似乎是一个糟糕的设计。制作这门课有什么更好的主意吗?
请注意,我不想像这样制作函数:
void func(const A& a,const A& b,A& result)
(很抱歉我找不到更好的问题标题:))
编辑
我的构造函数看起来像这样:
A(unsigned int SIZE)
{
// all of these are vectors and SIZE is about 1k
realData_.reserve(SIZE);
timePerUnit_.reserve(SIZE);
prob_.reserve(SIZE);
//....
// some math stuff for filling them
}
最佳答案
根据我对你问题的理解,你想写一个 A &func(const A& a,const A& b)
返回一个新构造的 A。但是作为优化你想修改 a 或 b如果将 func 的结果赋值给 a 或 b,则不构造新的 A。
当您编写 a = func(a, b)
时,这类似于 a.operator=(func(a, b))
。 func 不知道它的返回值是如何使用的,operator= 也不知道它的参数来自 func。如果您想针对该特殊情况进行优化,您需要为其编写额外的函数。
你可以编写一个未优化的和一个优化的版本:
A &func(const A& a, const A& b) { A c; ...; return c; }
void func(A& a, const A& b) { modify a; }
void func(const A& a, A& b) { modify b;}
// In case func(a,b)==func(b,a) for const a and const b you can write:
void func(const A& a, A& b) { func(b, a); }
或者你可以编写一个通用版本:
void func(const A& a, const A& b, A& result)
{
if(&result == &a)
optimized modify result;
else if(&result == &b)
optimized modify result;
else
unoptimized modify result;
}
如果幸运的话,您甚至不需要区分通用版本中的不同情况。但这取决于您正在进行的计算。
顺便说一句,如果您查看 STL,您会发现他们在做类似的事情。将 A 替换为字符串,将 func 替换为 operator+
,您将得到 string operator+ (const string& lhs, const string& rhs);
。该运算符将始终创建一个它返回的新对象。为了针对 str1 = str1 + str2;
的情况进行优化,STL 声明了一个额外的函数 operator+=
。这与您需要做的事情相同 - 只是您的函数名称为 func 而不是 operator ...。
关于c++ - 推断传递给一个函数的参数是否等于运算符中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22062478/