我正在阅读模板基础知识以及如何使用模板将参数传递给函数。下面的程序我试过,运行正常,没有任何编译错误。该函数正在修改传递给它的值,但rx
和cx
是常量,不能修改它们。因此,编译器应该抛出编译错误。
输出来了:
Param before : 27
Param after : 23
Param before : 27
Param after : 23
Param before : 27
Param after : 23
以下是完整的代码:
#include <iostream>
using namespace std;
template<typename T>
//void f(const T& param) // param is now a ref-to-const
void f(T param)
{
cout << "Param before : " << param << endl;
param = 23;
cout << "Param after : " << param << endl;
}
int main(int argc, char *argv[])
{
int x = 27;
const int cx = x;
const int& rx = x; // as before
// as before
// // as before
f(x); // T is int, param's type is const int&
f(cx); // T is int, param's type is const int&
f(rx); // T is int, param's type is const int&
return 0;
}
答案 0 :(得分:6)
当函数参数被定义为按值传递 时,函数模板param
中的f
也是如此:
template<typename T>
void f(T param) // <-- note T, and not T&
发生类型衰减,因此丢弃const
限定符。这种“取消资格”是有道理的,因为实际上是副本传递给函数的内容和不 原始对象(例如:原始对象)可能是const
,但其副本不必)。
该函数正在修改传递给它的值,但
rx
和cx
是常量,不能修改它们。
由于上面提到的类型衰减,在您的三种情况下T
被推断为int
(即:不合格)。该函数实际上正在修改传递的对象的非const
副本。因此,您没有看到任何编译错误。
答案 1 :(得分:3)
f
的每次使用都在修改传递给它的值的副本。这些副本都不是const &
,所以修改它们是完全没问题的
答案 2 :(得分:0)
使用模板参数中的T
,const
,volatile
和&
将被删除。同样的规则适用于auto
。这称为类型衰减。
因此在每种情况下只使用一个函数
void f (int param)
。
f(x); // argument is int, T is int, param's type is int
f(cx); // argument is const int, T is int, param's type is int
f(rx); // argument is const int &, T is int, param's type int