【问题标题】:How to define operator overloading for STL(C++).如何为 STL(C++) 定义运算符重载。
【发布时间】:2012-10-11 16:29:47
【问题描述】:

我有一个关于运算符重载的问题,定义一个类及其运算符重载函数很容易,如下代码所示:

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&lt;double&gt; &amp;weighting, const ABC &amp;priority_array=NULL) 可以有一个默认参数const ABC &amp;priority_array=NULL。我的问题是如果函数中的最后一个参数来自STL,例如const std::vector&lt;int&gt; &amp;priority_array=NULL,我们如何重新定义operator =。谢谢!

编辑: void gain_priority_array(const std::vector &weighting, const std::vector&lt;int&gt; &amp;sample=NULL) 失败!

【问题讨论】:

  • 你为什么不改变你的函数来接受指针,而不是引用?如果您只想传递 NULL 作为默认参数。
  • 顺便说一下,operator= 没有被默认参数调用。采用 int 的构造函数是:liveworkspace.org/code/84813303faa93e2b1359fa90c21adba8
  • 引用旨在避免为 NULL。尝试将 NULL 作为引用传递似乎是一个糟糕的代码概念。
  • @chris 是的,那么我的问题是关于 STL 组件,如何为 STL 向量定义构造函数?
  • @feelfree,看看这个:en.cppreference.com/w/cpp/container/vector/vector。唯一可以采用NULL 的构造函数是显式的,因此您需要类似于const std::vector&lt;int&gt; &amp;priority_array = std::vector&lt;int&gt;(NULL) 的东西,它转换为一个空向量。如果它应该转换为无向量,则必须使用指针。

标签: c++ stl


【解决方案1】:

您的误解始于添加 operator= 以允许该类型的默认参数的提议。在您的示例中,调用的不是operator=,而是ABC(int)。

使用std::vector 时您的代码未被接受的原因是NULL 转换为0(至少它几乎在您将看到的所有时间都转换为0),并且std::vector 的唯一构造函数可以取 0,即计算有多少项目的那个,被标记为显式。

要解决眼前的问题,可以将语法更改为:

const std::vector<int> &priority_array = std::vector<int>(0)

但是,这会引入不同的语义。通过您使用NULL,您似乎期望它不代表任何向量。如果没有给出,此版本将提供一个空向量供使用。它将 not 根本不是向量。如果你想要这种区别,你应该使用 boost 的可选库,或者一个简单的指针,因为引用不是正确的工具。

【讨论】:

    【解决方案2】:

    引用不能是NULL,你的问题与运算符重载无关。如果您希望能够将NULL 处理为默认值,请将参数类型从reference 切换为pointer。

    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
      }
    }
    

    【讨论】:

      【解决方案3】:

      当您使用= 创建引用时,您根本没有调用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
      

      当然,使用指针代替引用会更容易。

      【讨论】:

      • 谢谢,我知道了。我现在面临的问题是,如果 std::vector priority_array 是函数 gain_priority_array 的参数,并且该函数需要 std::vector priority_array 的默认构造函数,我该怎么办?
      • @chris 给了我正确的答案:const std::vector &priority_array = std::vector(NULL)。还是谢谢!
      猜你喜欢
      • 2012-03-08
      • 1970-01-01
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2011-11-15
      • 1970-01-01
      相关资源
      最近更新 更多