C++ 为什么';康斯特A&;绑定到模板参数中的()吗?

C++ 为什么';康斯特A&;绑定到模板参数中的()吗?,c++,C++,我试图做这个模板实例化,但它不工作。我得到了错误信息: prog.cpp:7:15:错误:“void f()”的模板id“f”与任何模板声明都不匹配 那么为什么它不能在模板行中工作呢?模板参数不能是临时对象。只有原语类型可以合理地进行比较,以确保完全相等,才可以是模板非类型参数。这包括 整数 统计员,以及 指向具有extern链接的对象的指针 但是 浮点数是不允许的,因为它们可能非常接近但不相等 static对象可能在不同的文件中具有相同的名称,但位置不同,这会使模板id在不同的文件中混淆

我试图做这个模板实例化,但它不工作。我得到了错误信息:

prog.cpp:7:15:错误:“void f()”的模板id“f”与任何模板声明都不匹配


那么为什么它不能在模板行中工作呢?

模板参数不能是临时对象。只有原语类型可以合理地进行比较,以确保完全相等,才可以是模板非类型参数。这包括

  • 整数
  • 统计员,以及
  • 指向具有
    extern
    链接的对象的指针
但是

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

(正如Pubby所指出的,
A()
实际上被解释为没有返回
A
的参数的函数类型。因此编译器无法找到包含两个类型参数的模板声明。)

模板参数不能是临时对象。只有原语类型可以合理地进行比较,以确保完全相等,才可以是模板非类型参数。这包括

  • 整数
  • 统计员,以及
  • 指向具有
    extern
    链接的对象的指针
但是

  • 浮点数是不允许的,因为它们可能非常接近但不相等
  • static
    对象可能在不同的文件中具有相同的名称,但位置不同,这会使模板id在不同的文件中混淆地解析为具有相同名称的不同实例化
  • 字符串文本也是如此
  • 临时对象没有一致的地址,因此无法传递指向临时对象的指针
  • 当您传递一个临时对象时,它的值甚至不能进行相等性测试,它永远不会让语言将一个模板实例化与另一个模板实例化相匹配
(正如Pubby所指出的,
A()
实际上被解释为没有返回
A
的参数的函数类型。因此编译器无法找到包含两个类型参数的模板声明。)

的可能重复

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

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

  • 整型或枚举型
  • 指向对象的指针或指向函数的指针
  • 对对象的左值引用或对函数的左值引用
  • 指向成员的指针
  • std::nullptr\u t
您正在传递的是一个右值(临时对象等,不能指定给),它不属于这些可能性中的任何一种

编辑: 看起来它实际上被解释为一个函数类型,但是您的模板签名需要一个类型为
a
(确切地说是
常数a&
)的非类型参数

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

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

  • 整型或枚举型
  • 指向对象的指针或指向函数的指针
  • 对对象的左值引用或对函数的左值引用
  • 指向成员的指针
  • std::nullptr\u t
您正在传递的是一个右值(临时对象等,不能指定给),它不属于这些可能性中的任何一种

编辑:
看起来它实际上被解释为一个函数类型,但是您的模板签名需要一个类型为
a
(确切地说是a
const a&
)的非类型参数。

您希望
a()
作为模板参数做什么?可能与
a()重复
作为模板参数执行吗?它的可能副本不是右值,它被解析为函数类型。@Pubby:甚至没有返回类型?它没有被解析为对默认构造函数的调用?@KarthikT返回类型是
a
。它不是右值,它被解析为函数类型。@Pubby:即使没有返回类型?它没有被解析为对默认构造函数的调用?@KarthikT返回类型是
a
template <class T, T> void f() {}

struct A {};

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

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