从另一个参数引用的模板可变参数

时间:2015-10-18 16:46:57

标签: c++ c++11 variadic-templates

我在模板中引用参数的方式遇到了麻烦(老实说,我强烈怀疑它不可能实现我想做的事情。)

它遵循我想做的一个例子(当然,这在语法上是不合法的,目的是给出哪个是目标的想法):

template<class C, Ret(C::*Member)(Params...), typename Ret, typename... Params>
class MyClass { }

换句话说,我想通过同时指定返回值和该方法的参数来引用类的成员。

不幸的是,我认为这样做的唯一方法就是下面的方法(好吧,它确实取决于那些类型名称的位置,无论如何它可能是一个有意义的例子):

template<typename Ret, typename... Params>
class MyClass {
public:
    template<class C, Ret(C::*Member)(Params...)>
    MyClass(C *c) { /* do something else and give sense to this class */ }
}

除了上面的那个,那就是通过引入一个模板化的构造函数来打破隔行扫描,还有另一种有效的方法来获得与唯一的类模板签名相同的结果吗?

我知道(非常简单)如果不是变量模板(例如,在Ret之前移动Member),如何实现它,但是可变参数(Params)具有放在模板列表的末尾,我不能以任何方式提及它。

1 个答案:

答案 0 :(得分:2)

根据this question,一个可行的解决方案可能是依靠默认值强制推算。

例如,以下代码应该有效:

class MyClass {
public:
    template <class C, typename R, typename... P, R(C::*M)(P...) = &C::foo>
    void bar(C *c) { }
};

我引用了相关链接问题的一部分(引用本身就是一个引用,我在循环中):

  

函数模板的模板参数包不能跟随另一个模板参数,除非该模板参数可以从函数模板的参数类型列表中推导出来或者具有默认参数。

因此,不应允许使用以下代码,即使它与GCC编译:

class MyClass {
public:
    template <class C, typename R, typename... P, R(C::*M)(P...)>
    void bar(C *c) { }
};

嗯,非常棘手,没有那么灵活的解决方案,说实话,我很久以前就进行了一些重构,但为了清楚起见,我已经决定添加一个答案并用一个片段关闭问题。编译。