2017-08-25 95 views
1

假設我有一個類用於表示任何維度中的典型數學向量。我想設計這個類,使它的構造函數接受任意數量的參數,將這些參數轉換爲long double類型,然後按照它們在參數列表中提供的相同順序將它們插入到「point_list」向量中。現在未知類型的可變參數構造函數參數列表

class Pvector 
{ 
    private: 
    std::vector<long double> point_list; 

    public: 
    // some magic constructor here 
}; 

,如果所有的參數都是同一類型的,這不會因爲我可以只使用一個初始化列表是困難的。但問題是任何參數都可能是不同的類型,並且這仍然需要接受任意數量的參數(至少一個)。從本質上講,我想能夠使用這樣的構造:

int i; 
float j; 
double k; 
long double l; 

Pvector vec1(i, j, k, l); 
Pvector vec2(k-i, 5, j); 
Pvector vec3(i, i, j, j, k, k, l, l); 
etc... 

我只是不知道是否有可能有一個可變參數的構造函數接受多種類型,然後暗中將它們轉換爲長雙打前插入他們進入矢量。是否有可能實現這一點,或者如果我想要一個可變參數構造函數,我的所有參數都必須是相同的類型嗎?

+4

你有沒有考慮只是採取'的std ::矢量'在構造函數中,讓'的std :: VECTOR'照顧它?你將不得不使用'Pvector vec1({i,j,k,l});'。 – nwp

+0

我不知道是否可以使用[參數包](http://en.cppreference.com/w/cpp/language/parameter_pack)與構造函數,但它可能值得嘗試。 –

+1

我不明白是什麼問題。 [只要做到這一點](https://ideone.com/ZvjlT9),沒有必要亂用variadic模板 – user463035818

回答

1

你可以做這樣的:。

class Pvector 
{ 
public: 
    template <typename ...Ts> 
    Pvector(Ts && ...ts) 
    { 
    point_list.reserve(sizeof...(Ts)); 
    init(std::forward<Ts>(ts)...); 
    } 

protected: 
private: 
    void init() { }; 

    template <typename ...Ts> 
    void init(long double x, Ts && ...ts) 
    { 
    point_list.push_back(x); 
    init(std::forward<Ts>(ts)...); 
    } 

    std::vector<long double> point_list; 
}; 
+0

事實上,它不會破壞一些複製/移動構造函數,這有點棘手。 – Jarod42

0

你可能會寫一個模板的構造函數(這是棘手的,人們可以預期,以避免匹配諸如Pvector(Pvector&)事情

class Pvector 
{ 
private: 
    std::vector<long double> point_list; 

public: 
    Pvector() = default; 

    Pvector(const Pvector&) = default; 
    Pvector(Pvector&&) = default; 

    // // SFINAE to avoid to match Pvector(Pvector& t) 
    template <typename T, 
       typename ... Ts, 
       std::enable_if_t<std::is_constructible<std::vector<long double>, T, Ts...>::value 
          && (!std::is_same<Pvector, std::decay_t<T>>::value 
           || sizeof...(Ts) != 0)>* = nullptr> 
    Pvector(T&& t, Ts&&... ts) 
    : point_list{t, ts...} {} 
    }; 

但它會簡單一些,只需將矢量作爲參數

class Pvector 
{ 
private: 
    std::vector<long double> point_list; 

public: 
    Pvector() = default; 

    Pvector(const Pvector&) = default; 
    Pvector(Pvector&&) = default; 

    Pvector(std::vector<long double>&& v) : point_list(std::move(v)) {} 
}; 

並調用它有額外{}

Pvector vec3({i, i, j, j, k, k, l, l});