将对基类的引用作为模板参数传递

时间:2017-09-11 10:09:40

标签: c++ templates

我有以下代码,我尝试为每个类的实例(可能已派生)专门化一个函数模板:

class Base {
};

class Derived:public Base {
};

template<Base& b>
void myfunction() {
   //use b somehow
}

Derived myobject;

int main() {
  myfunction<myobject>(); //this does not work
}

代码导致错误消息:

candidate template ignored: invalid explicitly-specified argument for template parameter 'b'

[live demo]

在给定静态Base对象Derived的情况下,如何将引用传递给myobject类型的静态实例?

1 个答案:

答案 0 :(得分:4)

虽然根据[temp.param]/4 可以将模板非类型参数声明为参考:

  

非类型模板参数应具有以下之一   (可选择cv-qualified)类型:

     
      
  • ...
  •   
  • 对对象的左值引用或对函数的左值引用,
  •   
  • ...
  •   

参数必须遵循[temp.arg.nontype]/2中的限制:

  

非类型模板参数的模板参数应为a   转换模板参数类型的常量表达式。   对于引用或指针类型的非类型模板参数,   常量表达式的值不应指(或指针   类型,不应是地址:

     
      
  • 子对象
  •   
  • ...
  •   

明确禁止您尝试做的事情。由于b最终会引用一个子对象。

将进行此编译的唯一解决方案是添加另一个重载:

template<Derived & d>
void myfunction()
{
   //use d somehow
}

所以你需要以某种方式提取公共代码。

或者,如果你有C ++ 17可用:

template<auto& b, std::enable_if_t<
                    std::is_base_of_v<Base, std::decay_t<decltype(b)>>
                  , void*> = nullptr>
void myfunction()
{
   //use b somehow
}

我建议你重新考虑一般方法。