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 ”。