c ++ templates为特定类型的类调用特定的构造函数

时间:2017-12-17 20:36:11

标签: c++ templates constructor

我正在尝试使用模板在c ++中创建通用二叉树。 因此,例如,Node类中的值类型可以是string,int或double。

我从字符串创建我的树,并在方法I中从字符串中提取单个数字,并为Node调用构造函数。

头文件中的节点类,没有其余的方法:

template <class T>
class Node {
public:
Node(const string value){
    this->value = value;
    this->leftChild = nullptr;
    this->rightChild = nullptr;
};
private:
T value;
Node *parent;
Node *rightChild;
Node *leftChild;
};

所以我要问的是如何为特定类型的Node类定义不同的构造函数,以便可以这样做:

Node<int> node(„2”); 

并定义和调用构造函数,如:

Node(const string value){
    this->value = stoi(value);
    this->leftChild = nullptr;
    this->rightChild = nullptr;
};

在我尝试只有一个构造函数之前,但是= =运算符:

void operator=(int &n,string &s){
n = stoi(s);
};

但是当它在课外定义时,编译器会说&#34;重载&#39; operator =&#39;必须是非静态成员函数&#34;

2 个答案:

答案 0 :(得分:0)

通常你会让你的构造函数和其他成员拿T,你有理由不去吗?

template<typename T>
struct Node
{
 T value;
Node * left, * right;

 Node(T const & value)
  : value(value), left(), right()
 { }
 ...
};

答案 1 :(得分:0)

首先,您需要了解成员初始化列表:C ++直接初始化对象。所以你有这样一个ctor:

Node::Node(std::string const& value)
    : value(value) // this line will need adjustment; see below
    , leftChild(nullptr)
    , rightChild(nullptr) {
}

对于通用数据结构,您最有可能实际调整ctor参数类型以匹配值类型。通用数据结构处理类型转换是不寻常的。但是,对于下面的讨论,我假设您要坚持使用std::string,例如,因为值是从文本文件中读取的。

如果您需要在不同类型之间进行转换,则需要使用通用类型转换器。它们分为两种:

  1. 现有的功能模板,例如boost::lexical_cast
  2. 使用特定的自定义点
  3. 这两种方法都有它们的位置,甚至可以将它们组合起来。它们的共同点是通用代码使用相同的语法,特定类型的处理在其他地方完成。

    使用boost::lexical_cast

    boost::lexical_cast的想法是将参数转换为字符序列,使用流解析结果以生成目标类型,并生成结果。实际实施经过大量优化,以避免对常见转化进行昂贵的操作,例如,从std::stringint的转换与stoi()实际上相同。

    它会像

    一样使用
    Node::Node(std::string const& value)
        : value(boost::lexical_cast<T>(value))
        , leftChild(nullptr)
        , rightChild(nullptr) {
    }
    

    使用自定义点

    另一种方法是定义特定的定制点,即可以由数据结构的用户定制的通用接口。这种方法的优点是具有更多的灵活性,例如,基于数据结构的使用方式进行适当的转换。使用合适的默认值可以避免必须由每个用户定义自定义点的缺点。

    假设用于转换的函数被称为my_convert,它可以像这样使用(还有其他方法来定义自定义点):

    Node::Node(std::string const& value)
        : value(my_convert<T>(value))
        , leftChild(nullptr)
        , rightChild(nullptr) {
    }
    

    此方法假定定义了一个主要模板,可能定义了合适的默认值,例如:

    template <typename T>
    T my_convert(std::string const& value) {
        return boost::lexical_cast<T>(value);
    }
    

    可以使用模板专业化为特定目标类型进行自定义:

    template <>
    int my_convert<int>(std::string const& value) {
        return std::stoi(value);
    }