Frage

Why doesn't the following code compile?

#include <iostream>
using namespace std;

struct CL1{};

struct CL2:CL1
{
    CL2(int){cout<<"int";}
};

void fnc(const CL1&)
{
}

int main()
{
    fnc(5);
    return 0;
}

Isn't two conversions working?

  1. user-defined conversion int to CL2
  2. standard conversion derived-to-base (CL2 to const CL1&)

The standard (2003) says:

A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-defined conversion (12.3) followed by a second standard conversion sequence.

Why does this not work?

War es hilfreich?

Lösung

There are no standard conversions involving references, so that rule isn't relevant here. Instead, we need the rules for initialising references, given in C++11 8.5.3. These are quite complicated; the relevant one here is the final bullet of clause 5 (for the case where the initialiser isn't reference-compatible with the reference type):

a temporary of type cv1 T1 is created and initialized from the initializer expression using the rules for a non-reference copy-initialization

Here, cv1 T1 is const CL1. There is no way to create a temporary T1 from int, and so the initialisation fails. The compiler isn't required to search all types derived from, or convertible to, the reference type; it only considers the reference type itself. You will have to specify that you want to create a CL2:

func(CL2(5));

which, being reference-compatible with const CL1, can be used to initialise the reference.

NOTE: I'm quoting C++11 since that's been the standard for some years. The rules and section numbers were essentially the same in C++03 (and indeed C++98).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top