13

このようなことを達成することは可能ですか?

template<typename Signature>
class Test
{
    public:
        //here I want operator () to respect the signature
};

Test<void(int)>          t1; //void operator()(int)
Test<void(int, float)>   t2; //void operator()(int, float)

戻りタイプは常にvoidです。

テンプレートパラメータとして関数シグネチャを送信したいと思います。これは可能ですか?私のコンパイラはまだこの機能をサポートしていないため、可変個引数テンプレートを使用できません。

4

2 に答える 2

17

可変個引数テンプレートを使用すると、署名をその部分に分解するために1つの部分的な特殊化を行うことができます。

template<typename Signature>
class Test;
// or the SFINAE-friendlier
//template<typename Signature>
//class Test {};
// or the hard-error-friendlier
//template<typename Signature>
//class Test {
//    static_assert(Bool<false, Signature>{},
//                  "template argument must be a signature returning void");
// // Bool is from http://flamingdangerzone.com/cxx11/2012/05/29/type-traits-galore.html#dependent_boolean
//};

template<typename... Args>
class Test<void(Args...)>
{
    public:
        void operator()(Args...) const;
};

可変個引数テンプレートがない場合は、引数の数ごとに1つの特殊化を行う必要があります。マクロは、それらすべてを生成するのに役立つ場合があります(Boost.PP、またはVisual Studioが標準ライブラリの可変個引数テンプレートをエミュレートするために使用するマクロ)。

于 2013-01-21T15:06:42.330 に答える
10
template <class Ty>
class Test; /* not defined */
template <class Ret, class Arg0>
class Test<Ret(Arg0)> { /* whatever */ }
template <class Ret, class Arg0, class Arg1>
class Test<Ret(Arg0, Arg1)> { /* whatever */ }
template <class Ret, class Arg0, class Arg1, class Arg2>
class Test<Ret(Arg0, Arg1, Arg2)> { /* whatever */ }

必要に応じて十分な議論ができるまで、退屈な繰り返しを続けます。TR1では、さまざまな関数オブジェクトテンプレートが10個の引数を処理できることが推奨されていました。これは通常、コーディングを簡素化するためにかなり洗練されたマクロで実装されましたが、ブルートフォースで実行できます。

于 2013-01-21T15:13:54.527 に答える