C ++:template函数,带有明确指定的引用类型作为类型参数 [英] C++: template function with explicitly specified reference type as type parameter
问题描述
我在玩C ++模板类型演绎,并管理编译这个小程序。
I was playing with C++ template type deduction and managed to compile this little program.
template<typename T>
void f(const T& val)
{
val = 1;
}
int main()
{
int i = 0;
f<int&>(i);
}
在所有主要编译器上编译,但我不明白为什么。为什么 f
分配给 val
标记为 const
?是这些编译器的错误还是它是根据C ++标准的有效行为?
It compiles on all major compilers but I do not understand why. Why can f
assign to val
, when val
is explicitly marked const
? Is it bug in these compilers or is it valid behavior according to the C++ standard?
推荐答案
§8.3.2[dcl.ref ] / p6:
§8.3.2 [dcl.ref]/p6:
如果 typedef name (7.1.3,14.1) * 或 decltype-specifier (7.1.6.2)
表示类型TR,它是对类型T的引用,尝试
创建类型lvalue reference to cv TR创建类型lvalue
reference to T,而尝试创建类型rvalue reference
to cv TR则创建类型TR。
If a typedef-name (7.1.3, 14.1)* or a decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a type T, an attempt to create the type "lvalue reference to cv TR" creates the type "lvalue reference to T", while an attempt to create the type "rvalue reference to cv TR" creates the type TR.
这称为参考折叠,并在C ++ 11中引入。在C ++ 03中,你的代码将是错误的,但有些编译器支持它作为一个扩展。
This is known as reference collapsing and is introduced in C++11. In C++03, your code would be ill-formed, but some compilers supported it as an extension.
注意在 const T& ;
, const
适用于 T
类型,因此当 T
是 int&
,则 const
将应用于引用类型本身这是无意义的,因为引用总是不可变的),而不是所指的类型。这就是为什么参考折叠规范忽略 TR
上的任何cv限定符。
Note that in const T &
, the const
applies to the type T
, so when T
is int &
, the const
would apply to the reference type itself (which is meaningless as references are immutable anyway), not the type referred to. This is why the reference collapsing specification ignores any cv-qualifiers on TR
.
* 根据§14.1[temp.param] / p3:
*A template type parameter is a typedef-name, per §14.1 [temp.param]/p3:
其标识符不符合省略号的类型参数
将其标识符定义为 typedef-name (如果使用
class
或typename
)或<在模板声明的范围中使用 template-name (如果使用
template
声明)。 $ b
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared with
class
ortypename
) or template-name (if declared withtemplate
) in the scope of the template declaration.
这篇关于C ++:template函数,带有明确指定的引用类型作为类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!