簡體   English   中英

C ++模板為特定類型的類調用特定的構造函數

[英]c++ templates call specific constructor for specific type of class

我正在嘗試使用模板在c ++中創建通用二進制樹。 因此,例如,Node類中的值類型可以是字符串,int或double。

我從字符串創建樹,並在方法中從字符串中提取單個數字,然后調用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);
};

但是,當在類之外定義它時,編譯器會說“重載的'operator ='必須是一個非靜態的成員函數”

通常,您會讓您的構造函數和其他成員采用T,您有理由不這樣做嗎?

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

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

首先,您需要了解成員初始化程序列表 :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. 使用特定的定制點

兩種方法都有它們的位置,甚至將它們組合起來可能是合理的。 它們的共同之處在於,通用代碼使用相同的語法,而特定於類型的處理則在其他地方完成。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM