Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't template type parameters inferred as 'const'? [duplicate]

Possible Duplicate:
deducing references to const from rvalue arguments

If I have

template<class T>
void foo(T &) { }

and I call it as foo((const int)5), given that the argument is a const int, why doesn't the compiler automatically infer T to be const int?

like image 915
user541686 Avatar asked Aug 13 '12 09:08

user541686


2 Answers

The type of an integer literal is int, not const int, according to C++03 Standard, clause 2.12.1.2.

The type of an integer literal depends on its form, value, and suffix. If it is decimal and has no suffix, it has the first of these types in which its value can be represented: int, long int;...

Update

Another relevant type deduction rule might be 14.8.2.1.2.

If P is not a reference type:

[...]

— If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction.

If P is a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction.

If P is a reference type, the type referred to by P is used for type deduction.

The code provided by OP wouldn't even compile because it's illegal to bind a non-const reference to rvalue.

like image 150
Andrey Avatar answered Oct 02 '22 03:10

Andrey


It does, if it's given a const type. Rvalues (prvalues in C++11) with non-class types, however, are never cv-qualified, even if you try to say they are: the expression ((const int)5) has type int. The reasoning here is that cv-qualifications only apply to objects, and temporaries of non-class types aren't objects, but pure values; cv-qualifications can't apply, because there's nothing to be const or volatile.

If you write:

int const i = 42;
foo( i );

, your template will instantiate with T = int const. (As you wrote it, the code shouldn't compile, because the deduced type is int, so the function takes an int&, which can't be initialized with an rvalue.)

like image 41
James Kanze Avatar answered Oct 02 '22 03:10

James Kanze