简体   繁体   English

如何使用模板调用内部类的构造函数?

[英]c++ How do i call a constructor of an interior class with templates?

I want to ceate an Nach obeject by calling Nach(3, a) where a is Mat object. 我想通过调用Nach(3,a)来终止Nach对象,其中a是Mat对象。 Some thing fails at this point. 此时有些事情失败了。 ( Line: Graph::Nach h = Graph::Nach(3,a); ) (线:Graph :: Nach h = Graph :: Nach(3,a);)

Nach is defined as in interior class of Graph. Nach在Graph的内部类中定义。 Graph uses two templates. 图使用两个模板。 Nach stands for a neighbor, Mat for material, Masch for machine. Nach代表邻居,Mat代表材料,Masch代表机器。

#include <iostream>
#include <vector>
#include <string>

class Mat {

    public:
        int _id;
        int _type;
        double _amount;

        Mat (int id, int type, double amount );
};
Mat::Mat(int id, int type, double amount){
    std::cout<<"Mat constuktor used"<<std::endl;
    _id = id; _type = type; _amount = amount;
};




class Masch {
    public:
        int _id;
        int _rez;
        double _count;

        Masch (int id, int rez, double count );

};
Masch::Masch(int id, int rez, double count){
    std::cout<<"Masch constuktor used"<<std::endl;
    _id = id; _rez = rez; _count = count;
};


template <class V, class E>
class Graph {
    public:
        class Nach {
            public:
                int _id;
                Mat _e;

                Nach(int id, Mat e);
        };

        int num;
        std::vector<V> nodes;
        std::vector<std::vector<Nach>> _nach;

        void addVertex(V t);
        void addEdge(V a, V b, E e);

        Graph();


};
template <class V, class E> Graph<V,E>::Graph(){
    std::cout<<"Graph constuktor used"<<std::endl;
    num = 0;    
}
template <class V, class E> Graph<V,E>::Nach::Nach(int id, Mat e){
    std::cout<<"Nach constuktor used"<<std::endl;
    _id = id; _e = e;
}
template <class V, class E> void Graph<V,E>::addVertex(V t){
    nodes.push_back(t);
    _nach.push_back(std::vector<Nach>());
    num++;
}
template <class V, class E> void Graph<V,E>::addEdge(V a, V b, E e){
    int i = a._id;
    int j = b._id;
    //Graph<V, E>::Nach x(3, e);
    //_nach[j].push_back(Nach(i,e));

}

int main (){

    Mat a= Mat(0,1,0.1); 
    //Mat b= Mat(1,1,0.3);

    Masch c = Masch(0,0,0.1);

    Graph <Masch, Mat> g = Graph<Masch, Mat>();

    //std::cout << a+b <<std::endl;
    //std::cout << c <<std::endl;

    Graph<Masch, Mat>::Nach h = Graph<Masch, Mat>::Nach(3,a);

    g.addVertex(c);
    g.addVertex(c);

    //g.addEdge(c,c,a);


    return 0;

}

I expect to creat an instance of the Nach class. 我希望创建一个Nach类的实例。

But it raises an calling error of the constructor of Mat. 但这会引起Mat构造函数的调用错误。 I dont see where "Mat" is called by the the call of "Nach" 我不知道“ Nach”的调用在何处调用“ Mat”

Error massenge 错误挑战

Hello.cpp: In instantiation of ‘Graph<V, E>::Nach::Nach(int, Mat) [with V = Masch; E = Mat]’:
Hello.cpp:94:57:   required from here
Hello.cpp:65:65: error: no matching function for call to ‘Mat::Mat()’
 template <class V, class E> Graph<V,E>::Nach::Nach(int id, Mat e){
                                                                 ^
Hello.cpp:16:1: note: candidate: Mat::Mat(int, int, double)
 Mat::Mat(int id, int type, double amount){
 ^
Hello.cpp:16:1: note:   candidate expects 3 arguments, 0 provided
Hello.cpp:7:7: note: candidate: constexpr Mat::Mat(const Mat&)
 class Mat {
       ^
Hello.cpp:7:7: note:   candidate expects 1 argument, 0 provided
Hello.cpp:7:7: note: candidate: constexpr Mat::Mat(Mat&&)
Hello.cpp:7:7: note: candidate expects 1 argument, 0 provided

When you invoke the Nach constructor, each of the members are default constructed and then the constructor body is executed. 调用Nach构造函数时,每个成员都是默认构造的,然后执行构造函数主体。 Mat does not have a default constructor. Mat没有默认的构造函数。 You cannot see the call to Mat() mentioned in the error message because the call is being generated by the compiler. 您看不到错误消息中提到的对Mat()的调用,因为该调用是由编译器生成的。 The solution is to use an initialisation list instead of constructing then assigning. 解决方案是使用初始化列表而不是构造然后分配。 Most of the time, a constructor body should be empty. 大多数时候,构造函数主体应该为空。

template <class V, class E>
Graph<V, E>::Nach::Nach(int id, Mat e)
  : _id{id}, _e{e} {}

This constructs the members directly instead of first default constructing them and then assigning to them (like you would in Java or something). 这将直接构造成员,而不是首先默认构造它们,然后再分配给它们(就像使用Java或类似方法一样)。 You should always use initialisation lists. 您应该始终使用初始化列表。

There are a few other things I should mention. 我还要提到其他几件事。

  • Using class in template parameter lists is a little old fashioned. 在模板参数列表中使用class有点过时。 class is allowed for backwards compatibility so it should be avoided. 允许向后兼容class ,因此应避免使用。 class was originally used to avoid adding another keyword to the language, typename was added later. class最初是为了避免在语言中添加另一个关键字,后来又添加了typename
  • Beginning identifiers with one or more _underscores_ usually isn't a good idea. 以一个或多个_underscores_开头的标识符通常不是一个好主意。 This is because identifiers beginning with underscores are reserved for the implementation so you could get collisions. 这是因为以下划线开头的标识符是为实现保留的,因此可能会发生冲突。
  • When using an initialisation list, the constructor parameters may have the same names as the members so the following is allowed and will behave as expected. 当使用初始化列表时,构造函数参数的名称可能与成员名称相同,因此允许以下内容并按预期运行。 There's rarely any reason to put underscores (or any other character sequence) in member names to avoid collisions. 几乎没有任何理由在成员名称中添加下划线(或任何其他字符序列)以避免冲突。

This is how I would implement the constructor. 这就是实现构造函数的方式。

template <typename V, typename E>
Graph<V, E>::Nach::Nach(const int id, const Mat e)
  : id{id}, e{e} {}

when creating Nach nested class, you need to create a Mat (with default constructor) as you initialize the _e member inside the constructor. 在创建Nach嵌套类时,需要在初始化构造函数内部的_e成员时创建Mat(具有默认构造函数)。

You should try to rewrite your constructor to copy the passed mat: 您应该尝试重写构造函数以复制传递的mat:

template <class V, class E> Graph<V,E>::Nach::Nach(int id, Mat e): _e(e) {
    // _e is now initialize from a e copy before entering here.
    std::cout<<"Nach constuktor used"<<std::endl;
    _id = id;  // this could be moved as welll
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++模板为特定类型的类调用特定的构造函数 - c++ templates call specific constructor for specific type of class 如何使用 cxx crate 调用 C++ 构造函数? - How do I call a C++ constructor using the cxx crate? 如何通过Rust FFI调用C ++构造函数? - How do I call a C++ constructor via Rust FFI? c ++创建结构数组时,如何使用结构数组内部的类的参数调用构造函数? - c++ How do I call a constructor with arguments of a class that is inside an array of structures when I create the array of structures? C ++如何从具有一个参数的派生类构造函数调用具有两个参数的超类构造函数? - C++ How can I call superclass constructor with two parameters from derived class constructor with one parameter? 使用 c++ 中的模板在派生的 class 中调用父 class 的构造函数的正确语法是什么? - What is the correct syntax to call the constructor of the parent class in a derived class with templates in c++? 如何在C ++中的同一类的构造函数中调用重载的构造函数? - How to call an overloaded constructor within a constructor of the same class in c++? C ++ - 如何从类的构造函数初始化单独类的构造函数? - C++ - How do I initialize a constructor of a separate class from the constructor of a class? 如何调用类成员的构造函数? - How do I call the constructor of a class' member? 如何调用基类构造函数? - How do I call the base class constructor?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM