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

Template variadic argument referenced from another argument

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

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

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

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

不幸的是,我看到的唯一方法是像下面这样的方法(好吧,这确实取决于在哪里需要这些类型名,无论如何它可能是一个有意义的例子):

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 */ }
}

除了上面的方法,即通过引入模板构造函数来打破交错,还有另一种有效的方法来获得与唯一 class 模板签名相同的结果吗?

我知道(非常简单)如果不是可变参数模板(例如,在 Member 之前移动 Ret),但是可变参数模板(Params ) 必须放在模板列表的末尾,我无法以任何方式引用它。

根据 ,一个可行的解决方案可能是依赖于默认值强制的扣除。

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

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

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

A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list of the function template or has a default argument.

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

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

好吧,非常棘手,不是那么灵活的解决方案,老实说,我很久以前就进行了一些重构,但为了清楚起见,我决定添加一个答案并用一个片段结束问题编译。