【问题标题】:Declare constructors of class with a constant array (or arrays) as an argument in C++?在 C++ 中用常量数组(或数组)作为参数声明类的构造函数?
【发布时间】:2021-06-29 05:57:29
【问题描述】:

我是 C++ 新手,听说过如此强大的技术 - 模板。

这是我的类中的构造函数

    node(const double f) {
        this->type = FLOAT;
        this->data.f = f;
    }
    node(const int i) {
        this->type = INTEGER;
        this->data.i = i;
    }
    //construct a vector
    node(const vector<int> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr[i]));
        }
    } 
    node(const vector<double> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr[i]));
        }
    } 

它帮助我做这种事情

node* obj_i = new node({{1, 0},{0, -1}});
node* obj_f = new node({{1.0, 0.0},{0.0, -1.0}});

我确实必须为整数和浮点类型的数组写下初始化程序两次。有什么办法可以使用模板来完成,然后用一个替换最后两个函数?

谢谢

UPD 我更深入并声明了矩阵的构造函数并得到了错误

    //construct a matrix    
    node(const vector<vector<int>> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr[i]));
        }
    } 
    node(const vector<vector<double>> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr[i]));
        }
    }  
error: call of overloaded 'node(<brace-enclosed initializer list>)' is ambiguous
     node* matrix2 = new node({{0.0,7.7}, {3.3,-9.2}});

我似乎是我的技术根本上错了......

【问题讨论】:

标签: c++ templates vector


【解决方案1】:

非常感谢您的回答(对不起,我没有足够的积分来投票)。但我确实必须修改建议的解决方案。 这对我来说非常有效

    //construct integers, floats
    node(const double f) {
        this->type = FLOAT;
        this->data.f = f;
    }
    node(const int i) {
        this->type = INTEGER;
        this->data.i = i;
    }
    //construct a vector
    template<typename T>
    node(initializer_list<T> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr.begin()[i]));
        }
    }
    //construct a matrix
    template<typename T>
    node(initializer_list<initializer_list<T>> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr.begin()[i]));
        }
    } 

用法

    node* matrix1 = new node({{1,3},{2,3}});
    node* matrix2 = new node({{2,7},{4,5}});

【讨论】:

    【解决方案2】:

    为此,您必须声明一个模板。

    template<typename T>
    node(const vector<T> arr) {
        this->type = LIST;
        for (int i=0; i<arr.size(); ++i) {
            this->data.args.push_back(new node(arr[i]));
        }
    }
    

    此外,您必须相应地对代码进行更改

    node* obj_i = new node<int>({{1, 0},{0, -1}});
    node* obj_f = new node<double>({{1.0, 0.0},{0.0, -1.0}});
    

    【讨论】:

      【解决方案3】:

      最简单的解决方案是为任何向量声明一个模板:

      template<typename vector_t>
      node(const vector<vector_t> &arr) {
          this->type = LIST;
          for (int i=0; i<arr.size(); ++i) {
              this->data.args.push_back(new node(arr[i]));
          }
      }
      

      是的,使用引用有一个很好的理由——这样可以避免对作为参数传入的任何向量进行完全无用且毫无意义的副本。

      唯一的缺点是这也将参与std::vector&lt;char *&gt; 的重载解决方案。这可能会以眼泪和大量令人困惑的错误消息而告终。最好让它仅参与intdouble 的重载解决方案,从而产生更可口的“嘿,没有这样的构造函数”错误消息。这将需要更多的工作,并且将是一个不同的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-01
        • 2017-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多