模板推导:const引用和const指针

时间:2016-10-21 02:26:53

标签: c++ templates pointers reference template-deduction

.count
我现在很困惑。根据 Effective Modern c ++

  

重要的是要认识到const仅被by-value忽略   参数。正如我们所见,对于引用的参数或   指向const的指针,在类型中保留了expr的constness   扣。

我认为这意味着

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???

所以我认为在上面的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

2 个答案:

答案 0 :(得分:1)

仅忽略顶级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指针差异的指针

答案 1 :(得分:1)

  

所以我认为当上面的f(px)时,px应该是int *,但实际上它是const int *。

关键是参数的类型,按值传递传递的参数/指针的行为会发生变化。

当按值传递时,将忽略参数本身的常量。对于指针参数,指针的常量被忽略(const指针 - &gt;指针),但仍保留指针的常量(指向const的指针 - &gt;指向const的指针)。

它确实有意义,因为当传递指针时,指针本身被复制,但指针对象是相同的,它们都指向同一个东西,所以保留了指针的常量;从调用者的角度来看,他们不希望修改对象,以后可能会使用它。虽然传递了一个引用(实际上引用并不重要),但是你将获得一个全新的值,它与原始值无关,然后忽略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*