我有以下代码,我尝试为每个类的实例(可能已派生)专门化一个函数模板:
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'
在给定静态Base
对象Derived
的情况下,如何将引用传递给myobject
类型的静态实例?
答案 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
}
我建议你重新考虑一般方法。