[英]Template Class wrong copy constructor called
Solution 解
To avoid the problem with the std::auto_ptr one can switch to boost::shard_ptr or C++11 std::shared_ptr. 为了避免std :: auto_ptr的问题,可以切换到boost :: shard_ptr或C ++ 11 std :: shared_ptr。
I get an error that the wrong copy constructor is called in my template class: 我得到一个错误,在我的模板类中调用了错误的复制构造函数:
MPINetworkCode.hpp: error: no matching function for call to
MPILib::MPINode<double>::MPINode(MPILib::MPINode<double>)
MPINode.hpp: note: candidate is:
MPILib::MPINode<double>::MPINode(MPILib::MPINode<double>&)
Here are the code lines which result in this error. 以下是导致此错误的代码行。
int MPINetwork<WeightValue>::AddNode(const AlgorithmInterface<WeightValue>& alg,
NodeType nodeType) {
MPINode<WeightValue> node = MPINode<WeightValue>(alg, nodeType,
tempNodeId, _nodeDistribution, _localNodes);
_localNodes.insert(std::make_pair(tempNodeId, node));
}
What is wrong with this code, and why is the wrong copy constructor is called? 这段代码有什么问题,为什么调用错误的拷贝构造函数? In a previous version of this class without templates this worked fine.
在没有模板的此类的以前版本中,这工作正常。
Here the header of the related classes. 这里是相关类的标题。 The template implementation are in a header file.
模板实现位于头文件中。
Here the MPINetwork: 这里是MPINetwork:
template <class WeightValue>
class MPINetwork: private boost::noncopyable {
public:
explicit MPINetwork();
~MPINetwork();
/**
* Adds a new node to the network
* @param alg The Algorithm of the actual node
* @param nodeType The Type of the Node
* @return returns the NodeId of the generated node
*/
int AddNode(const AlgorithmInterface<WeightValue>& alg, NodeType nodeType);
//lot of code
};
And the second MPINode, where the default copy constructor should be called: 第二个MPINode,应该调用默认的复制构造函数:
template <class Weight>
class MPINode {
public:
/**
* Constructor
* @param algorithm Algorithm the algorithm the node should contain
* @param nodeType NodeType the type of the node
* @param nodeId NodeId the id of the node
* @param nodeDistribution The Node Distribution.
* @param localNode The local nodes of this processor
*/
explicit MPINode(const AlgorithmInterface<Weight>& algorithm, NodeType nodeType,
NodeId nodeId,
const boost::shared_ptr<utilities::NodeDistributionInterface>& nodeDistribution,
const std::map<NodeId, MPINode<Weight> >& localNode);
virtual ~MPINode();
Time Evolve(Time time);
void ConfigureSimulationRun(const SimulationRunParameter& simParam);
void addPrecursor(NodeId nodeId, const Weight& weight);
void addSuccessor(NodeId nodeId);
NodeState getState() const;
void setState(NodeState state);
void receiveData();
void sendOwnState();
private:
void waitAll();
std::vector<NodeId> _precursors;
std::vector<Weight> _weights;
std::vector<NodeId> _successors;
std::auto_ptr<AlgorithmInterface<Weight> > _algorithm;
NodeType _nodeType;
NodeId _nodeId;
const std::map<NodeId, MPINode>& _refLocalNodes;
boost::shared_ptr<utilities::NodeDistributionInterface> _nodeDistribution;
NodeState _state;
std::vector<NodeState> _precursorStates;
std::vector<boost::mpi::request> _mpiStatus;
};
template<class Weight>
MPINode<Weight>::MPINode(const AlgorithmInterface<Weight>& algorithm, NodeType nodeType,
NodeId nodeId,
const boost::shared_ptr<utilities::NodeDistributionInterface>& nodeDistribution,
const std::map<NodeId, MPINode>& localNode) :
_algorithm(algorithm.Clone()), _nodeType(nodeType), _nodeId(nodeId), _nodeDistribution(
nodeDistribution), _refLocalNodes(localNode) {
}
Your problem is essentially caused by this member: 您的问题基本上是由该成员引起的:
std::auto_ptr<AlgorithmInterface<Weight> > _algorithm;
std::auto_ptr
's copy constructor doesn't really copy, it transfers ownership. std::auto_ptr
的复制构造函数并没有真正复制,它会转移所有权。 Because of this it takes a non-const reference to its argument, not a const reference. 因此,它需要对其参数进行非const引用,而不是const引用。
This means that when the compiler comes to generate the copy constructor for an MPINode
specialization it cannot generate a copy constructor that takes a const reference to another MPINode
, it can only generate one that takes a non const reference. 这意味着当编译器为
MPINode
生成复制构造函数时,它不能生成一个复制构造函数,它将const引用带到另一个MPINode
,它只能生成一个带有非const引用的复制构造函数。
In this initialization, the temporary MPINode<WeightValue>
cannot bind to the non-const reference parameter that the generated copy constructor requires. 在此初始化中,临时
MPINode<WeightValue>
无法绑定到生成的复制构造函数所需的非const引用参数。
MPINode<WeightValue> node = MPINode<WeightValue>(alg, nodeType,
tempNodeId, _nodeDistribution, _localNodes);
How to fix this depends on your design. 如何解决这个问题取决于您的设计。 It might be that supplying a user-defined copy constructor that takes const reference and properly clones the
_algorithm
member is the correct approach. 可能是提供一个用户定义的复制构造函数来获取const引用并正确克隆
_algorithm
成员是正确的方法。
Your compiler seems to be generating a copy constructor for you that accepts an argument of type MPILib::MPINode<double>&
. 您的编译器似乎正在为您生成一个复制构造函数,它接受类型为
MPILib::MPINode<double>&
。 Try defining your own copy constructor that takes the type const MPILib::MPINode<double>&
. 尝试定义自己的复制构造函数,其类型为
const MPILib::MPINode<double>&
。 The initialization of the variable node
in AddNode
is invoking the copy constructor, and the compiler does not let you pass a temporary into a function that expects a modifiable reference. AddNode
中的变量node
的初始化正在调用复制构造函数,并且编译器不允许您将临时函数传递给期望可修改引用的函数。
Because you have a std::auto_ptr<AlgorithmInterface<Weight> >
(which doesn't have a "normal" copy constructor taking a const-reference, but unfortunately has a perverse one taking a reference) as a data member, the compiler couldn't generate the default copy constructor taking a const-reference. 因为你有一个
std::auto_ptr<AlgorithmInterface<Weight> >
(没有“普通”拷贝构造函数采用const-reference,但不幸的是有一个反常的参与者)作为数据成员,编译器无法使用const-reference生成默认的复制构造函数。 In that case, when it is possible, the compiler generates the one taking a non-const reference. 在这种情况下,当可能时,编译器生成采用非const引用的那个。 Your code tries to call this one, and it fails.
您的代码尝试调用此代码,但它失败了。
Disable it NOW , as the generated "copy" constructor actually steals the data member from its argument. 禁用它吧 ,作为生成的“复制”构造实际上抢断它的参数数据成员。 Then, implement your own copy constructor with the behavior as you desire.
然后,根据需要使用行为实现自己的复制构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.