我有一个与运算符重载有关的问题,很容易定义一个类及其运算符重载函数,如下面的代码所示:
typedef std::vector<std::vector<int> > ARRAY;
class ABC
{
public:
ABC():a(0)
{
};
int a;
ABC& operator = (int value)
{
a = value;
return *this;
}
ABC(int value)
{
a = value;
}
};
void obtain_priority_array(const std::vector<double> &weighting, const ABC &priority_array=NULL)
{
}
int main()
{
vector<double> weighting;
weighting.push_back(0.8);
weighting.push_back(0.9);
weighting.push_back(0.6);
weighting.push_back(0.3);
weighting.push_back(0.5);
ABC test;
obtain_priority_array(weighting, test);
return 0;
}
在上面的示例中,class ABC
重新定义了operator =
,以便函数void obtain_priority_array(const std::vector<double> &weighting, const ABC &priority_array=NULL)
可以具有默认参数const ABC &priority_array=NULL
。我的问题是,如果函数中的最后一个参数来自STL,例如const std::vector<int> &priority_array=NULL
,我们如何重新定义operator =
。谢谢!
编辑:
void obtain_priority_array(const std :: vector&amp; weighting,const std::vector<int> &sample=NULL
)失败!
答案 0 :(得分:3)
引用不能是NULL
,您的问题与运算符重载无关。如果您希望能够将NULL
作为默认值处理,请将参数类型从引用切换为指针。
void obtain_priority_array( const std::vector<double>& weighting,
const ABC *priority_array = NULL)
{
if( priority_array == NULL ) {
// blah
} else {
// more blah
}
}
另一种选择是使用Boost.Optional之类的东西来表示可选参数。
typedef boost::optional<ABC> maybe_ABC;
void obtain_priority_array( const std::vector<double>& weighting,
const maybe_ABC& priority_array = maybe_ABC() )
{
if( !priority_array ) {
// blah
} else {
// more blah
}
}
答案 1 :(得分:3)
您的误解始于添加operator=
以允许该类型的默认参数的提议。在您的示例中,不是operator=
被调用,而是ABC(int)
。
使用std::vector
时未接受代码的原因是NULL
转换为0(至少几乎所有时间都会看到它),并且是唯一的构造函数可以取0的std::vector
,计算了多少项的const std::vector<int> &priority_array = std::vector<int>(0)
被标记为显式。
要解决当前问题,可以将语法更改为:
NULL
然而,这引入了不同的语义。通过使用{{1}},看起来你期望它代表没有向量。如果没有给出,该版本将提供一个空向量供使用。 不根本不是矢量。如果你想要这种区别,你应该使用boost的可选库或简单的指针,因为引用不是正确的工具。
答案 2 :(得分:1)
当您使用=
创建引用时,您根本不会调用operator=
。您正在初始化参考。
您可以创建类的静态实例来表示空值,而不是使用NULL
。
static const ABC ABC_NULL;
void obtain_priority_array(const std::vector<double> &weighting, const ABC &priority_array=ABC_NULL)
{
if (&priority_array == &ABC_NULL) // the default was used
当然,使用指针而不是引用会更容易。