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

Template variadic argument referenced from another argument

本文关键字:参数 变参 另一个 引用      更新时间:2023-10-16

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

下面是一个我想要做的事情的例子(当然,这在语法上是不合法的,目的是给出哪个是目标的概念):

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)必须躺在模板列表的末尾,我不能以任何方式引用它。

根据这个问题,一个可行的解决方案可能是依赖于默认值强制的演绎。

例如,下面的代码应该是有效的:
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) { }
};

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