56

オブジェクトジェネレータパターンに関するこの質問は、それを自動化する方法について考えさせられました。

std::make_pair基本的に、のような関数の作成を自動化std::bind1stしたいstd::mem_funので、テンプレートクラスタイプごとに異なる関数を作成する代わりに、すべてのケースを一度に処理する単一の可変個引数テンプレートテンプレート関数を作成できます。この関数の使用法は次のようになります。

make<std::pair>(1, 2);         // equivalent to std::make_pair(1, 2)
make<std::binder2nd>(&foo, 3); // equivalent to std::bind2nd(&foo, 3);

この関数を書くことは可能makeですか?これを試しましたが、GCC4.5または4.6では機能しません。

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
    return TemplateClass<Args...>(std::forward<Args>(args)...);
}

電話をかけようとすると(例make<std::pair>(1, 2)

error: no matching function for call to 'make(int, int)'

ここのどこかで構文が間違っていますか?
それとも、これは正しく、GCCは間違っていますか?
それとも、これはC ++ 0xでは基本的に不可能ですか?

[編集]

提案N2555は、これが許可されていることを示唆しているようであり、GCCはGCC4.4でそれを実装したと主張しています

4

3 に答える 3

49

その通りです。私はそれが機能することを期待します。したがって、GCCはそれを拒否することに誤りがあると思います。FWIW:

#include <utility>

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
    return TemplateClass<Args...>(std::forward<Args>(args)...);
}

int main() {
  make<std::pair>(1, 2);
}


// [js@HOST2 cpp]$ clang++ -std=c++0x main1.cpp
// [js@HOST2 cpp]$
于 2011-06-26T20:45:35.917 に答える
7

これはおそらくGCCの癖です。以下を開発スナップショットで動作させることができます(現在4.6のコピーはありません):

template<
    template<typename...> class TemplateClass
    , typename... Args

    , typename Result = TemplateClass<Args...>
    // Also works with the arguably more correct
    // , typename Result = TemplateClass<
    //     typename std::decay<Args>::type...
    // >
>
Result
make(Args&&... args)
{ /* as before */ }
于 2011-06-26T20:45:36.933 に答える
4

これはかなり間違っていますmake_shared-たとえば、。ポイントmake_sharedは、それを使用することで実行時の効率が節約されることです。しかし、使用しようとするとどうなりますmake<std::shared_ptr>か?それがうまくいくとは思わないでください。または、コンストラクター引数の一部のみがテンプレート引数であり、残りはテンプレート引数ではない型についてはどうでしょうか。たとえば、make<std::vector, int>(other_vector.begin(), other_vector.end());-イテレータのタイプは参加しませんが、とにかくそれらを渡します。

ジェネリックmake関数を書くことは不可能です。

スタンダードに関しては、まあ、それ以来簡単に削除できたはずです。FDISを確認する必要があります。

于 2011-06-26T20:25:25.617 に答える