33

なぜstd::make_tuple存在するのですか?テンプレート パラメーターを回避できるため、関数によって入力する必要がある文字数が減る状況があることはわかっています。しかし、それが唯一の理由ですか?std::tuple他のクラステンプレートにはそのような機能がないのに、その機能が存在することの何が特別なのですか? std::tupleそのような状況でより頻繁に使用できるからですか?


std::make_tuple文字数を減らす2 つの例を次に示します。

// Avoiding template parameters in definition of variable.
// Consider that template parameters can be very long sometimes.
std::tuple<int, double> t(0, 0.0); // without std::make_tuple
auto t = std::make_tuple(0, 0.0);  // with std::make_tuple

// Avoiding template parameters at construction.
f(std::tuple<int, double>(0, 0.0)); // without std::make_tuple
f(std::make_tuple(0, 0.0));         // with std::make_tuple

しかし、上記のように、他の多くのクラス テンプレートにはこのような関数はありません。

4

4 に答える 4

36

コンストラクターに引数推定を使用できないためです。明示的に記述する必要があります std::tuple<int, double>(i,d);

これにより、タプルを作成して別の関数にワンショットで渡すのがより便利になります。

takes_tuple(make_tuple(i,d))takes_tuple(tuple<int,double>(i,d))

iまたはの型が変更されたときに変更する場所が 1 つ少なくなりましたd。特に、古い型と新しい型の間で変換が行われる可能性がある場合はそうです。

を書くことができればstd::tuple(i,d);make_*(おそらく)冗長になるでしょう。

A a();(ここで理由を尋ねないでください。構文がデフォルトのコンストラクターを呼び出さないのと同様の理由である可能性があります。C++ 構文にはいくつかの厄介な特徴があります。)

更新注: Danielが正しく気づいている ように、c++17 が拡張され、テンプレート引数の推定がコンストラクターに対して機能し、そのような委譲は廃止されます。

于 2015-12-09T14:06:08.327 に答える
9

提案N3602 : Template parameter deduction for constructorsで、必要な理由make_tupleと他のさまざまな make_* ユーティリティの理論的根拠を見つけることができます。

このペーパーでは、関数のテンプレート パラメーター推定をテンプレート クラスのコンストラクターに拡張することを提案します。問題と解決策を説明する最も明確な方法は、いくつかの例を使用することです。

以下を定義したとします。

vector<int> vi1 = { 0, 1, 1, 2, 3, 5, 8 }; 
vector<int> vi2; template<class Func> 
    class Foo() { 
        public: Foo(Func f) : func(f) {} 
        void operator()(int i) { os << "Calling with " << i << endl; f(i); } 
        private: 
        Func func;
    };

現在、テンプレート クラスをインスタンス化する場合は、テンプレート パラメーターを指定するか、「make_*」ラッパーを使用するか、関数のテンプレート パラメーター推定を利用するか、完全にパントする必要があります。

pair<int, double> p(2, 4.5); 
auto t = make_tuple(4, 3, 2.5); 
copy_n(vi1, 3, back_inserter(vi2)); // Virtually impossible to pass a lambda to a template class' constructor
for_each(vi.begin(), vi.end(), Foo<???>([&](int i) { ...}));

この提案はEWG issue 60で追跡されていることに注意してください。

于 2015-12-09T14:20:09.173 に答える