2017-08-25 21 views
1

どの次元の典型的な数学的なベクトルを表すように設計されたクラスがあるとします。このクラスを設計して、そのコンストラクタが任意の数の引数をとり、それらの引数をlong double型に変換し、それらをパラメータリストに与えられたのと同じ順序で "point_list"ベクトルに挿入するようにしたいと思います。Variadicのコンストラクタパラメータ不明なタイプのリスト

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

    public: 
    // some magic constructor here 
}; 

ここで、すべてのパラメータが同じタイプであれば、初期化リストを使用するだけで問題はありません。しかし問題は、どのパラメータも異なるタイプのものである可能性があり、これはまだいくつでもパラメータ(少なくとも1つ)を受け入れる必要があることです。

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... 

私はちょうどそれが複数のタイプを受け入れた後、暗黙的に挿入する前に長いdouble型に変換する可変引数のコンストラクタを持つことが可能かどうか分からない:基本的に、私はこのようなコンストラクタを使用できるようにしようとしていますそれらをベクターに挿入します。これを達成することは可能ですか、私はvariadicコンストラクタが必要な場合、すべてのパラメータは同じ型でなければなりませんか?あなたはこのようにそれを行うことができ

+4

であなただけのコンストラクタで 'のstd ::ベクトル'を取り、 'STDをさせる考えがあります::それの世話をするvector'? 'Pvector vec1({i、j、k、l});'を使う必要があります。 – nwp

+0

[parameter packs](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

あなたは1つが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}); 
関連する問題