[英]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. 我还要提到其他几件事。
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
。 _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. 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.