模板推导:const引用和const指针
template deduction: const reference and const pointer
template <typename T>
void f(T t)
{}
int x = 1;
const int & rx = x;
const int * px = &x;
f(rx); // t is int
f(px); // t is const int *, instead of int *, WHY???
我现在很困惑。根据 Effective Modern c++,
It’s important to recognize that const is ignored only for by-value
parameters. As we’ve seen, for parameters that are references-to- or
pointers-to-const, the constness of expr is preserved during type
deduction.
我觉得是
template <typename T>
void f(T * t)
{}
f(px); // t is const int *
template <typename T>
void f(T & t)
{}
f(cx); // t is const int &
template <typename T>
void f(T t)
{}
f(value); // const or volatile of value will be ignored when the type of the parameter t is deduced
所以我觉得上面f(px)
时,t
应该是int *
,但实际上是const int *
.
为什么reference的const
被忽略了,pointer的const
却没有?
或者,为什么 rx
const int &
?
仅忽略顶级 const/volatile 限定符。所有其他都是你类型的内在品质。换句话说,您正在复制一个指针——这意味着该函数对一个副本进行操作,并且对其进行的任何修改(如分配另一个变量的地址)都不会修改原始指针。但是如果你传递一个指向 const int 的指针,让函数修改整数是非常违反直觉的。
template <typename T>
void f(T t)
{
t = &another_variable; // ok
}
f(px);
和
void f(T t)
{
*t = 42; // not ok!
}
f(px); // secretly modifying `x` through a pointer to const...
参考:this answer 指向 const 的指针与 const 指针的区别
So I think when f(px)
above, px
should be int *
, but in fact it is const int *
.
重点是参数的类型,按值传递和passed-by-reference/pointer的行为发生变化。
按值传递时,忽略参数本身的常量性。对于指针参数,指针的常量性被忽略(const pointer -> pointer),但pointee的常量性仍然保留(pointer to const -> pointer to const)。
这是有道理的,因为当传递一个指针时,指针本身被复制,但是指针对象是相同的,它们都指向同一个东西,所以指针对象的常量性被保留;从调用者的角度来看,他们不希望修改对象,他们可能会在以后使用它。而传递一个引用(这里引用其实并不重要),你会得到一个全新的值,与原来的值无关,然后constness被忽略。
正如书上的以下解释,当const指针指向const(aconst char* const
)传递时,
template<typename T>
void f(T param); // param is still passed by value
const char* const ptr = // ptr is const pointer to const object
"Fun with pointers";
f(ptr); // pass arg of type const char * const
param
推导的类型将是 const char*
。
template <typename T>
void f(T t)
{}
int x = 1;
const int & rx = x;
const int * px = &x;
f(rx); // t is int
f(px); // t is const int *, instead of int *, WHY???
我现在很困惑。根据 Effective Modern c++,
It’s important to recognize that const is ignored only for by-value parameters. As we’ve seen, for parameters that are references-to- or pointers-to-const, the constness of expr is preserved during type deduction.
我觉得是
template <typename T>
void f(T * t)
{}
f(px); // t is const int *
template <typename T>
void f(T & t)
{}
f(cx); // t is const int &
template <typename T>
void f(T t)
{}
f(value); // const or volatile of value will be ignored when the type of the parameter t is deduced
所以我觉得上面f(px)
时,t
应该是int *
,但实际上是const int *
.
为什么reference的const
被忽略了,pointer的const
却没有?
或者,为什么 rx
const int &
?
仅忽略顶级 const/volatile 限定符。所有其他都是你类型的内在品质。换句话说,您正在复制一个指针——这意味着该函数对一个副本进行操作,并且对其进行的任何修改(如分配另一个变量的地址)都不会修改原始指针。但是如果你传递一个指向 const int 的指针,让函数修改整数是非常违反直觉的。
template <typename T>
void f(T t)
{
t = &another_variable; // ok
}
f(px);
和
void f(T t)
{
*t = 42; // not ok!
}
f(px); // secretly modifying `x` through a pointer to const...
参考:this answer 指向 const 的指针与 const 指针的区别
So I think when
f(px)
above,px
should beint *
, but in fact it isconst int *
.
重点是参数的类型,按值传递和passed-by-reference/pointer的行为发生变化。
按值传递时,忽略参数本身的常量性。对于指针参数,指针的常量性被忽略(const pointer -> pointer),但pointee的常量性仍然保留(pointer to const -> pointer to const)。
这是有道理的,因为当传递一个指针时,指针本身被复制,但是指针对象是相同的,它们都指向同一个东西,所以指针对象的常量性被保留;从调用者的角度来看,他们不希望修改对象,他们可能会在以后使用它。而传递一个引用(这里引用其实并不重要),你会得到一个全新的值,与原来的值无关,然后constness被忽略。
正如书上的以下解释,当const指针指向const(aconst char* const
)传递时,
template<typename T>
void f(T param); // param is still passed by value
const char* const ptr = // ptr is const pointer to const object
"Fun with pointers";
f(ptr); // pass arg of type const char * const
param
推导的类型将是 const char*
。