Search code examples
c++c++11constructorimplicit-conversioncopy-initialization

C++ copy initialization + implicit constructor call = fail


This code:

class foo
{
    int x;
public:
    foo(int x) : x(x) { }
    int get() const { return x; }
    //...
};

class bar
{
    int x;
public:
    bar(const foo& x) : x(x.get()) { }
    int get() const { return x; }
    bar& operator =(const foo& rhs) { x = rhs.get(); return *this; }
    //...
};

void func()
{
    foo f = 3;
    bar b = 3;
    b = 7;
    //...
}

errors out on the bar b = 3 line (g++ 4.7.1 with -fstd=gnu++11):

error: conversion from 'int' to non-scalar type 'bar' requested

However, I'm providing a bar constructor that takes a foo, and ints can be implicitly converted to foo as shown by the line preceding it. So, what is going wrong?

By the way, for several reasons it is undesirable to force conversion to foo using foo(3) because that would make my actual code ugly to use and read.


Solution

  • I'm providing a bar constructor that takes a foo, and ints can be implicitly converted to foo as shown by the line preceding it. So, what is going wrong?

    Chained-conversion is not allowed in C++, which means the (chained) conversion cannot occur:

    int -> foo -> bar  //not allowed (chained conversion)
    

    even though the followings are given:

    int -> foo  //given
    foo -> bar  //given
    

    So if you want int -> bar to work, then add another constructor taking int to class bar.