模板推导: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++,
重要的是要认识到const仅在按值时被忽略参数。正如我们所看到的,对于引用- or的形参指向const的指针,expr的const性在类型期间保留扣除。
我想它的意思是
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 *
。
为什么引用的const
被忽略,但指针的const
没有?或者,为什么rx
不是const int &
呢?
所以我认为上面的
f(px)
,px
应该是int *
,但实际上是const int *
。
关键是形参的类型,按值传递和按引用传递/指针传递的行为改变。
按值传递时,实参本身的constness将被忽略。对于指针形参,忽略指针的constness (const pointer ->指针),但仍然保留了指针的常量(指向const ->指向const的指针
这是有意义的,因为当传递指针时,指针本身被复制,但指针是相同的,它们都指向同一个东西,所以保持了指针的constness;从调用者的角度来看,他们不希望修改对象,他们以后可能会使用它。当传递一个引用时(引用在这里实际上并不重要),你将得到一个全新的复制值,它与原始值无关,然后忽略constness。
正如书中所解释的,当const指针指向const (a const 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*
。
只忽略顶级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...
参考:这是const指针与const指针差异的答案
- 将const引用参数初始化为默认参数会导致悬空引用吗
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 如何在构造函数中传递 const 引用时强制编译器不接受右值
- 为什么我需要三个嵌套的大括号来调用赋值运算符,将const引用到二维数组
- 对临时对象的Const引用不会延长其生存期
- 对 const 引用参数使用默认值会导致崩溃
- 在运算符重载中使用带有 const 引用的 friend 函数
- C++通过 const 引用传递时不调用派生类函数
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- 为什么要返回对小类成员的 const 引用?
- C - 最好将枚举类作为值或const引用
- RVO:返回由值传递的值,即使显式分配给 const 引用也是如此
- const引用与可变成员的对象
- 每当传递lvalue时,每当通过rvalue传递时,将const引用存储
- 对类成员而不是 getter 的 Const 引用
- 从类型 'Matrix&' 的右值初始化 类型的非 const 引用无效 'Matrix'
- 在函数中使用 const 引用参数访问函数中成员的最佳实践 C++.
- STD ::配对的const引用如何工作
- 为什么我的C 函数拒绝返回const引用