C++:具有明确指定的引用类型作为类型参数的模板函数

标签 c++ function-templates

我在玩 C++ 模板类型推导并设法编译了这个小程序。

template<typename T>
 void f(const T& val)
 {
   val = 1;
 }


 int main()
 {
    int i = 0;
    f<int&>(i);
 }

它可以在所有主要编译器上编译,但我不明白为什么。为什么 f 可以赋值给 val,而 val 被显式标记为 const?它是这些编译器中的错误还是符合 C++ 标准的有效行为?

最佳答案

§8.3.2 [dcl.ref]/p6:

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 中,您的代码可能格式错误,但一些编译器支持它作为扩展。

请注意,在 const T & 中,const 适用于类型 T,因此当 Tint &const 将应用于引用类型本身(这毫无意义,因为引用无论如何都是不可变的),而不是引用的类型。这就是为什么引用折叠规范会忽略 TR 上的任何 cv 限定符。


*根据 §14.1 [temp.param]/p3,模板类型参数是一个typedef-name:

A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared with class or typename) or template-name (if declared with template) in the scope of the template declaration.

关于C++:具有明确指定的引用类型作为类型参数的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27256516/

相关文章:

c++ - 在多处理器机器上执行 C++ 程序

c++ - 当方法可用时,我如何专门化模板?

c++ - 需要默认参数值的模板函数的首选设计是什么?

c++ - 将参数转发到可变参数模板函数时如何添加参数值?

c++ - 具有包扩展的可变参数函数模板不在最后一个参数中

c++ - 在Windows中编译OpenSSL-生成的LIB为DLL文件使用了错误的名称

c++ - 使用 C++ 类成员函数作为 C 回调函数

c++ - 如何使用 boost 从 com 端口读取未定义数量的字节?

c++ - 将 shared_ptr<T> 向上转换为 shared_ptr<void> 会导致未定义的行为吗?

C++ 函数模板的奇怪类型转换错误