3

解决方案

为了避免 std::auto_ptr 的问题,可以切换到 boost::shard_ptr 或 C++11 std::shared_ptr。

我收到一个错误,在我的模板类中调用了错误的复制构造函数:

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>&)

以下是导致此错误的代码行。

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

这段代码有什么问题,为什么调用了错误的复制构造函数?在没有模板的此类的先前版本中,这工作正常。

这里是相关类的标题。模板实现在头文件中。

这里是 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

};

第二个 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) {

}
4

3 回答 3

5

您的问题本质上是由该成员引起的:

std::auto_ptr<AlgorithmInterface<Weight> > _algorithm;

std::auto_ptr的复制构造函数并没有真正复制,它转移了所有权。正因为如此,它对其参数采用非常量引用,而不是 const 引用。

这意味着当编译器为特化生成复制构造函数时,MPINode它不能生成一个接受 const 引用的复制构造函数MPINode,它只能生成一个接受非 const 引用的复制构造函数。

在此初始化中,临时MPINode<WeightValue>无法绑定到生成的复制构造函数所需的非常量引用参数。

MPINode<WeightValue> node = MPINode<WeightValue>(alg, nodeType, 
      tempNodeId, _nodeDistribution, _localNodes);

如何解决此问题取决于您的设计。可能是提供一个用户定义的复制构造函数,它接受 const 引用并正确克隆_algorithm成员是正确的方法。

于 2012-06-05T08:46:34.720 回答
2

您的编译器似乎正在为您生成一个接受 type 参数的复制构造函数MPILib::MPINode<double>&。尝试定义您自己的采用 type 的复制构造函数const MPILib::MPINode<double>&nodein变量的初始化AddNode是调用复制构造函数,编译器不允许您将临时值传递给需要可修改引用的函数。

于 2012-06-05T08:46:50.903 回答
1

因为您有一个std::auto_ptr<AlgorithmInterface<Weight> >(它没有采用 const 引用的“正常”复制构造函数,但不幸的是有一个不正当的引用)作为数据成员,编译器无法生成采用 const 的默认复制构造函数-参考。在这种情况下,如果可能,编译器会生成带有非常量引用的那个。您的代码尝试调用它,但它失败了。

你应该怎么做

立即禁用它,因为生成的“复制”构造函数实际上从其参数中窃取了数据成员。然后,使用您想要的行为实现您自己的复制构造函数。

于 2012-06-05T08:47:12.013 回答