2

我正在尝试执行此模板实例化,但它不起作用。我收到错误:

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() {}

这很奇怪,因为当我在 main 中执行此操作时,它可以工作:

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

那么为什么它在模板行中不起作用呢?

4

2 回答 2

2

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

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

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

(正如 Pubby 所指出的,A()它实际上被解释为没有返回参数的函数的类型A。所以编译器只是找不到采用两个类型参数的模板声明。)

于 2013-01-04T03:08:40.393 回答
2

非类型模板参数可能重复

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

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

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

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

编辑:

看来它实际上被解释为函数类型,但您的模板签名需要类型的非类型参数A(确切地说是 a const A&

于 2013-01-04T03:11:13.120 回答