2

Consider the following code:

template <typename T>
void foo(const T& param) {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    std::cout << param;
}

int main()
{
    foo<const int&>(5);
    return 0;
}

The output gives:

void foo(const T&) [with T = const int&]                                                                                                                       
5 

Here apparently T is resolved to const int& (as the printout says, since I explicitly forced so). However, this seems to create a problem: The function signature takes a parameter of type const T&, and in this case it would expand to const const int& &, which is not legal syntax in C++.

But the program indeed runs fine. What's going on here?

Update: I know that T& & would collapse to T&. However, in this case, the double const is also not legal if you write them explicitly, and I don't see that template collapsing rule mention this part.

Update 2: Compiling const const int x = 1; gives error: duplicate ‘const’. Multiple const is not allowed in c++ (but surprisingly in c it's okay).

OneZero
  • 11,556
  • 15
  • 55
  • 92

1 Answers1

5

C++ types are not formed by textual replacement. const T& where T is void * is void* const &, not const void *&.

Your code attempts to form the type "lvalue reference to const T" where T is "lvalue reference to const int". By the reference collapsing rules, that will instead form the type "lvalue reference to const int".

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 1
    Worth noting what happens if you do have redundant `const` on the same layer, though, for example `const T` where `typedef const int T` – Ben Voigt Oct 21 '18 at 04:56