The example code is taken from: http://en.cppreference.com/w/cpp/types/add_cv (I modified a little.)
struct foo
{
void m() { std::cout << "Non-cv\n"; }
void m() const { std::cout << "Const\n"; }
};
template<class T>
void call_m()
{
T().m();
}
int main()
{
call_m<foo>();
call_m<const foo>(); //here
}
And the output is:
Non-cv
Non-cv
in the second call, T
is const qualified, so T()
should call the const version, right? or are there some special rules I missed?
The relevant quote from the standard is 5.2.3 [expr.type.conv]/2
The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete ob- ject type or the (possibly cv-qualified) void type, creates a prvalue of the specified type,which is value- initialized (8.5; no initialization is done for the void() case). [Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting prvalue (3.10). —end note ]
The wording in the standard explicitly mentions (in non-normative form) that for non-class types the const-volatile qualification is dropped, but in your case the type is a class, and the note does not apply. It seems that VS is applying the same rule that is applied for non-class types.