C++ 为什么不';t模板类型参数推断为';常数';?

C++ 为什么不';t模板类型参数推断为';常数';?,c++,templates,constants,type-parameter,C++,Templates,Constants,Type Parameter,可能重复: 如果我有 template<class T> void foo(T &) { } 模板 void foo(T&){} 我把它叫做foo((const int)5),既然参数是const int,为什么编译器不自动推断t为const int?根据C++03标准第2.12.1.2条,整数文本的类型是int,而不是const int 整型文字的类型取决于其形式、值和后缀。 如果它是decimal且没有后缀,则它在中具有这些类型中的第一个 它的值可以表示为:int,

可能重复:

如果我有

template<class T>
void foo(T &) { }
模板
void foo(T&){}

我把它叫做
foo((const int)5)
,既然参数是
const int
,为什么编译器不自动推断
t
const int

根据C++03标准第2.12.1.2条,整数文本的类型是
int
,而不是
const int


整型文字的类型取决于其形式、值和后缀。 如果它是decimal且没有后缀,则它在中具有这些类型中的第一个 它的值可以表示为:int,long int

更新

另一个相关的类型扣除规则可能是14.8.2.1.2

如果p不是引用类型:

[……]

-如果A是cv限定类型,则A类型的顶级cv限定符 类型推断时忽略

如果p是cv限定类型,则p类型的顶级cv限定符 类型推断时忽略

如果p是引用类型,则p引用的类型将用于类型 扣除额


OP提供的代码甚至不会编译,因为将非常量引用绑定到右值是非法的。

如果给定了常量类型,它会这样做。带有 然而,即使你试图说,非班级类型永远不会符合简历要求 它们是:表达式
((const int)5)
具有类型
int
。推理 这里是简历资格只适用于对象,和临时的 非类类型不是对象,而是纯值;简历资历不能 应用,因为没有任何内容是
const
volatile

如果你写:

int const i = 42;
foo( i );
,您的模板将用
T=int const
实例化。(如你所愿 编写它时,代码不应该编译,因为推导出的类型 是
int
,因此函数采用
int&
,这不能是
用右值初始化。)

哇,真的吗?我不知道,谢谢你让我知道。。。我想我在问题中有一个坏例子来说明我的观点。我只是在问题中修正了它。但问题仍然存在,即使我显式地将其转换为
const int
,所以这不是真正的问题,对吗?@Mehrdad,到底是哪个“问题”?@SingerOfTheFall:它在标题中。当我将
const
参数传递给
foo
时,例如在我的(固定)示例中,
t
为什么不被推断为给定的
const
类型?@Mehrdad:如果您实际传递了
const
左值参数,比如
const int I=42;傅(42),。问题不在于
const
-ness,而在于lvalue-/rvalueness。你的评论很好,但不适用于他的例子。他不是用整型文字来实例化,而是用一个cast表达式。只有第二个引号的最后一点适用,因为在他的例子中,
P
是一个引用类型(没有顶级常量)。他的代码没有编译(或导致在一个坏编译器中出现
t=int
)的原因是因为表达式
((int const)5)
是非类类型的右值,而非类类型的右值没有cv限定符(即使您明确地说应该有)。请澄清一下,“非类类型”到底是什么这就是你说的
int
int&
const int
const int&
?(我不确定我对这个词的含义是否了解得足够透彻,以至于还不足以理解您的答案。)因为我们正在讨论向它添加cv限定符,所以类型必须是
int
。至少在原始代码中,类型应该是
int const
(在强制转换之后),除非非类类型的右值没有cv修饰符。(有趣的是注意到转换为
int const&
应该可以工作。)哇,所以
struct Foo{};foo((const foo)foo())工作正常?!我从来不知道+1为什么
int
与任意的
struct
有任何不同,这完全没有道理,但这似乎是正确的解释,谢谢..@Mehrdad History。这是没有意义的,除了在C中,rValk从来没有CV限定,C++想要表现相同(尽管在这种情况下,我不知道它可能是什么)。但类类型是否为const会影响函数重载解析:例如,在
foo().bar()
中调用哪个函数。因此cv限定符必须对类类型产生影响。无论如何,这就是我所给出的理由。@ FredOverflow类型,因为 const 是C++类型系统的一部分。(假设如果C++已经走了这条路线,则<代码> 42 < /代码>的类型将是<代码> int const ,并且不会有任何类型,只是“代码> int ”。