我有一个具有可变成员函数的类:
class class_name {
template<ArgTypes.. args>
some_return_type memberMethod(ArgTypes... args) {
//stuff...
}
}
我需要强制在类定义块中实例化此方法。 我在类定义块之外省略了方法名,因为该类是由一堆宏生成的。
我尝试通过复制指向专用成员函数的指针(伪代码)来强制实例化:
template<typename Self, typename RetType, typename... ArgTypes>
struct force_instantation_imlp<Self, RetType, type_placeholder, type_placeholder<ArgTypes...>> {
force_instantation_imlp() {
using instate = RetType (Self::*)(ArgTypes...);
instate force = &Self::memberMethod<ArgTypes...>;
}
};
class class_name {
template<ArgTypes.. args>
some_return_type memberMethod(ArgTypes... args) {
//stuff...
}
force_instantation_imlp<class_name, some_return_type, rest_of_types_deduced_from_context> force_virtual_instantation;
}
type_placeholder
只是一个“冻结”参数包的辅助模板。
遗憾的是,这给了我一个编译错误
error: expected primary-expression before ‘...’ token instate force = &Self::memberMethod<ArgTypes...>;
我猜这个错误是因为成员函数是一个可变参数模板。
有没有办法在类定义块中强制使用可变参数模板成员函数实例化?
答案 0 :(得分:1)
(重复我对OP的评论。)
行instate force = &Self::memberMethod<ArgTypes...>;
中的实际问题是缺少template
关键字:
instate force = &Self::template memberMethod<ArgTypes...>;
参见,例如Where and why do I have to put the “template” and “typename” keywords?
实际上,这里不需要显式模板参数[over.over] / 1:
在某些上下文中使用不带参数的重载函数名称来解析指向过载集中特定函数的成员函数的指针。函数模板名称被认为是在这种上下文中命名一组重载函数。选择的函数是其类型与上下文中所需的目标类型的函数类型相同的函数。
即,因为instate
定义了函数类型,编译器能够确定为名称Self::memberMethod
选择哪个重载( here:模板特化)。
可能有更简单的解决方案来强制实例化函数模板,即使在类定义中也是如此。我想到的是使用私人typedef
,例如using dummy = integral_constant<instate, &Self::memberMethod>;
(或static constexpr instate dummy = &Self::memberMethod;
)。
我很好,但不是100%确定typedef
强制成员函数模板的实例化。当需要该函数的定义时,函数模板被实例化,并且ODR建议这是这样的情况:“如果它是唯一的查找结果,则其名称显示为可能被评估的表达式的函数是odr-used或者一组重载函数的选定成员“和”每个程序应该只包含在该程序中使用的每个非内联函数或变量的一个定义“ 子>