为什么不是const A&绑定到模板参数中的A()?

时间:2013-01-04 03:06:11

标签: c++

我试图进行此模板实例化,但它无法正常工作。我收到了错误:

  

prog.cpp:7:15: error: template-id 'f<const A&, A()>' for 'void f()' does not match any template declaration

template <class T, T> void f() {}

struct A {};

template void f<const A &, A()>();

int main() {}

这很奇怪,因为当我在主要工作时它起作用:

int main() {
    const A &a = A(); // no error
}

那为什么它不能在模板行中运行?

2 个答案:

答案 0 :(得分:2)

模板参数不能是临时对象。只有可以合理地比较精确相等的原始类型才可以是模板非类型参数。这包括

  • 整数,
  • 枚举器和
  • 指向extern链接的对象的指针。

但是

  • 不允许使用浮点数,因为它们可能非常接近但不相等
  • static个对象可能具有相同的名称但在不同的文件中具有不同的位置,这会使模板ID容易混淆地解析为不同文件中具有相同名称的不同实例
  • 同样适用于字符串文字
  • 临时对象没有一致的地址,因此您无法将指针传递给一个
  • 你传递的临时对象的值,甚至不能测试是否相等,永远不会让语言与另一个模板实例化匹配!

(正如Pubby所说,A()实际上被解释为没有参数返回A的函数的类型。所以编译器只是找不到带有两个类型参数的模板声明。)< / p>

答案 1 :(得分:2)

Non-type template parameters

可能重复

这些是模板非类型参数的规则

  

非类型模板参数应具有以下(可选的cv限定)类型之一:

     
      
  • 整数或枚举类型,
  •   
  • 指向对象或指向函数的指针,
  •   
  • 对对象的左值引用或对函数的左值引用,
  •   
  • 指向成员的指针,
  •   
  • std::nullptr_t
  •   

你传递的是一个RValue(无法分配的临时对象等),它不属于任何这些可能性。

编辑:

它似乎被解释为函数类型,但您的模板签名需要类型为A的非类型参数(恰好是const A&