5

テンプレート パラメーター T を持つクラス テンプレート Templ があり、Templ クラスには obj と呼ばれる型 T のデータ メンバーがあります。引数を obj のコンストラクターに転送する可変引数コンストラクター テンプレートを作成しました。

template <class T>
class Templ
{
public:
     template <class... Args> explicit Templ (Args&&... args)
     : obj (std::forward<Args>(args)...)
     {
     }
private:
     T obj;
};

ここで、型 T が init-list コンストラクターを持つクラスである可能性があることに気付きました。Templ を介してアクセスできるようにしたいと考えています。std::list::emplaceだから私は何をチェックstd::make_sharedしました。私のような可変関数がありますが、init-list を取るオーバーライドはありません。何らかの理由で。

最初の質問:なぜですか?std::list<T>つまり、init-list ctor でクラス T を使用し、次に?を使用するとどうなるでしょうか。list::emplace に initializer_list を取るバージョンがないのはなぜですか? たぶん、私がそうすべき正当な理由があるのか​​もしれません...だから私は知りたいです。

また、STL の機能に関係なく、init-list ctor を適切な設計として提供する必要がありますか? つまり、可変引数 ctor のようなものですよね?ユーザーが任意の型またはクラス T を選択して Templ<> で使用できるようにし、T に定義された任意の ctor を直接呼び出すことができるようにします。

4

1 に答える 1

3

転送initializer_listコンストラクターの問題は、最も些細な引数の型を除いてすべてが推定できないことです (テンプレートは常に初期化リストの型を推測するとは限りません)。

#include <map>
template<typename T> struct U {
   T t;
   template<typename...A> explicit U(A&&...a): t(std::forward<A>(a)...) {}
   template<typename L, typename = typename std::enable_if<
      std::is_constructible<T, std::initializer_list<L>>::value>::type>
      explicit U(std::initializer_list<L> l): t(l) {}
};
U<std::map<int, int>> m{{{0, 1}, {2, 3}}};  // fails, couldn't deduce 'L'

ほとんどの場合、記述m{std::initializer_list<...>{...}}しなければならないので、プリミティブだけにそれを提供する意味はあまりありません。

興味深い引数がコンテナ型にある可能性が高いと思われる場合は、オプションでテンプレートの initializer_list 構築をサポートし、おそらくコンテナをラップするinitializer_listで採用されているアプローチを見ることができます。

于 2013-02-11T12:09:29.723 に答える