この質問オブジェクトジェネレータパターン は、自動化する方法について考えさせられましたそれ。
基本的に、_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
を書くことは可能ですか?私はこれを試しましたが、GCC 4.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でそれを実装したと主張している 。
そうです。私はそれが機能すると期待しています。したがって、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]$
これはおそらくGCCの癖です。 devスナップショットを使用するには、次のものを入手できます(現在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 */ }
これはまったく間違っています。たとえば、_make_shared
_を考えます。 _make_shared
_のポイントは、使用時に実行時の効率の節約があることです。しかし、_make<std::shared_ptr>
_を使用しようとするとどうなりますか?それがうまくいくとは思わないでください。または、コンストラクタ引数の一部のみがテンプレート引数であり、残りはそうではない型についてはどうでしょうか?たとえば、make<std::vector, int>(other_vector.begin(), other_vector.end());
-イテレータの型は参加しませんが、とにかくそれらを渡します。
汎用のmake
関数を書くことは不可能です。
標準については、それ以降、簡単に削除できたはずです。 FDISを確認する必要があります。