- A+

In the code below, why do the two ways of invoking `fun`

: `fun(num)`

and `fun<const int>(num)`

, give a different result when compiling?

`#include <iostream> using namespace std; template<typename T, typename = typename enable_if<!std::is_same<int, T>::value>::type> void fun(T val) { cout << val << endl; } int main(void) { const int num = 42; fun(num); //ERROR! fun<const int>(num); //Right return 0; } `

The parameter is declared as pass-by-value; then in template argument deduction, the top-level const qualifier of the argument is ignored.

Before deduction begins, the following adjustments to P and A are made:

1) If P is not a reference type,

a) ...

b) ...

c) otherwise, if A is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction:

So given `fun(num)`

, the template parameter `T`

will be deduced as `int`

, not `const int`

.

If you change the parameter to pass-by-reference, the `const`

part will be preserved. e.g.

`template<typename T, typename = typename enable_if<!std::is_same<int, T>::value>::type> void fun(T& val) `

Then for `fun(num)`

, `T`

will be deduced as `const int`

.