Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can const be applied to template argument types outside of the parameter list in C++?

I am studying C++ templates, and I got stuck thinking about the interaction between const and types that are arguments to template functions. Specifically, I am thinking about how consts interact with template types when applied outside of the template parameter list.

I have tried looking for this interaction in C++ Primer 5th ed (Lippman) and in the C++11 standard draft, but const in this context is either not explicitly mentioned or (in the case of the standard) rather complex in its description (I'm still somewhat new to C++).

Here is a code example of my problem:

template<typename T>
const T & constify(T & t) {
    return t;
}

...

int* i = 0x12345678; 
constify(i);

I have two different expectations of the return type:

  1. The deduced return type is const (int *) &, i.e the const is applied afterwards, so that we cannot modify the int pointer but we can modify what it points to.
  2. The deduced return type is const int * &, i.e all declarators and qualifiers are applied all at once instead of as in 1. Here, we can no longer modify the int pointed to by the integer, but we can modify the pointer itself.

For me, the first one makes more sense because it has a natural "substitution-like" rule behind it, similar to typedef. But my question is; which of these (if any) is correct and why?

like image 995
Simon Sirak Avatar asked Apr 12 '19 15:04

Simon Sirak


2 Answers

Template type substitutions are not textual, so do not think of them in terms of the textual type definition.

In your example, T is deduced to be int * - let's call it intptr. You are making const reference to it, so return value becomes const intptr&. That means, that the pointer itself can't be modified through this reference, but the value it points to can be modified.

Last, but not the least, you could have easily verifed your assumptions before asking the question :)

like image 58
SergeyA Avatar answered Oct 08 '22 15:10

SergeyA


The 1st one is correct, and the return type would be int * const &, i.e. the reference to const pointer to non-const int; not const int * &, i.e. the reference to non-const pointer to const int.

const is qualified on T itself, when T is a pointer const T would be a const pointer but not a pointer to const pointee.

like image 30
songyuanyao Avatar answered Oct 08 '22 16:10

songyuanyao