4

我有一个具有可变成员函数的类:

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

我猜这个错误是由于成员函数是可变参数模板这一事实造成的。

有没有办法在类定义块中强制可变参数模板成员函数实例化?

4

1 回答 1

2

(重复我对 OP 的评论。)

该行中的实际问题instate force = &Self::memberMethod<ArgTypes...>;是缺少template关键字:

instate force = &Self::template memberMethod<ArgTypes...>;

参见,例如,我必须在哪里以及为什么要放置“template”和“typename”关键字?

实际上,这里 [over.over]/1 不需要显式模板参数:

在某些上下文中,使用不带参数的重载函数名称被解析为 [...] 指向重载集中特定函数的成员函数的指针。函数模板名称被认为是在此类上下文中命名一组重载函数。选择的函数是其类型与上下文中所需的目标类型的函数类型相同的函数。

即,因为instate定义了函数类型,编译器能够确定为名称选择哪个重载(这里:Self::memberMethod模板特化) 。


可能有更简单的解决方案来强制实例化函数模板,即使在类定义中也是如此。我想到的一个是使用私人typedef喜欢using dummy = integral_constant<instate, &Self::memberMethod>;(或 a static constexpr instate dummy = &Self::memberMethod;)。

我很确定,但不是 100% 确定typedef强制实例化成员函数模板。函数模板在需要定义该函数时被实例化,并且 ODR 建议这里是这种情况:“名称显示为潜在求值表达式的函数,如果它是唯一的查找结果或选定的一组重载函数的成员”“每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的一个定义”

于 2013-08-21T15:36:29.953 回答