推导传递给一个函数的参数是否等于运算符中的参数

Deduce if parameters passed to one funcion are equal to parameters in an operator

本文关键字:参数 函数 是否 运算符 一个      更新时间:2023-10-16

我有这个类:

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。但作为优化,如果func的结果被分配给a或b,你想修改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,而不是运算符。

如果您确实不想使用:

void func(const A& a, const A& b, A& result)

然后,您可以通过使用第三个参数的指针而不是bool来摆脱单个重载,例如:

A func(const A& a, const A& b, const A* resultPlace = NULL)
{
if (resultPlace == &a) {
// Do in place stuff with a
return a;
}
else if (resultPlace == &b) {
// Do in place stuff with b
return b;
}
else {
A c;
// whatever
return c;
}
}

当然,你可以这样称呼它:b = func(a, b, &b);

不确定你是否能做得更好,但我怀疑你是否能做到你的问题标题特别要求的。