Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top