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

使用可变参数模板,您可以进行部分专业化以将签名分解为其部分:

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;
};

如果没有可变参数模板,您必须为每个数量的参数进行一个特化。宏可能有助于生成所有这些(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 */ }

Continue the tedious repetition until you have enough arguments for your needs. In TR1 it was recommended that the various function object templates be able to handle 10 arguments. This was typically implemented with fairly sophisticated macros to simplify coding, but it can be done by brute force.

于 2013-01-21T15:13:54.527 回答