【问题标题】:Forcing variadic template member function instantiation in class在类中强制可变参数模板成员函数实例化
【发布时间】:2013-08-21 11:08:37
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您可以只使用auto 而不是instate : auto force = &amp;Self::memberMethod&lt;ArgTypes...&gt;;。这样您就不用编写 using 来定义类型了。
  • 您是否尝试过在instate force = &amp;Self::memberMethod&lt;ArgTypes...&gt;; 中省略显式模板参数?
  • @Nawaz 好点。我还是没有养成c++11的习惯。问题仍然存在。
  • ...我想你错过了template:&amp;Self::template memberMethod&lt;ArgTypes...&gt;;
  • @Marcin instate force = &amp;Self::memberMethod; 起作用的原因是编译器可以在该上下文中根据所需的类型(instate 的类型)来选择重载。对于decltype,这当然是不可能的。因此,在 decltype 中,您需要强制转换或显式指定重载(例如,使用显式模板参数)。这当然是没用的,因为如果您可以访问这些参数类型,您可以直接指定没有decltype 的函数类型。

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


【解决方案1】:

(从我的 cmets 重复到 OP。)

instate force = &amp;Self::memberMethod&lt;ArgTypes...&gt;; 行中的实际问题是缺少 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 选择哪个重载(此处: 模板特化)。


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多