8

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?

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
Frahm
  • 805
  • 2
  • 9
  • 16
  • 3
    Looks like a bug in MSVC, since g++-4.8 and clang++-3.2 calls const function. – ForEveR May 22 '13 at 11:51
  • Yeah, this is a bug that has come up before. MSVC ignores const qualifiers of `T` in `T()`. – Joseph Mansfield May 22 '13 at 11:52
  • 1
    The language wording require that inside your template, if `T` is a **non-class** type with possible const-volatile qualification, the qualification is dropped when generating the *prvalue*. It seems that VS is using the same logic also for class types (incorrectly) – David Rodríguez - dribeas May 22 '13 at 11:56
  • @sftrabbit Oh, almost the same question, except the title, so I didn't see that one. Thanks. and sorry for the duplication. – Frahm May 22 '13 at 12:01
  • @Frahm It's more their fault for asking two questions in one. – Joseph Mansfield May 22 '13 at 12:02
  • @sftrabbit Thanks, anyway, I should link this post to that one, and close the questions. – Frahm May 22 '13 at 12:04

1 Answers1

3

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.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489