Multiple explicit constructors and implicit conversion

I have a class like this:

class Foo
{
    private:
        std::string m_data;

    public:
        Foo() = default;

        explicit Foo(double value);
        explicit Foo(float value);
        explicit Foo(int64_t value);
        explicit Foo(bool value);
        explicit Foo(const std::string& value);
        explicit Foo(const char* value);
};

… because I’d like to be able to construct Foo instances from integers, booleans, floats, doubles, and so on.

Let’s say I have another class Bar, which has a method that takes a reference to const Foo:

void append(const Foo& foo);

Why does the compiler complain when I do the following?

instanceOfBar.append(3.5);

Reference to type Foo could not bind to an rvalue of type ‘float’

instanceOfBar.append(4);

Reference to type Foo could not bind to an rvalue of type ‘int’

instanceOfBar.append(true);

Reference to type Foo could not bind to an rvalue of type ‘bool’

I am using GCC 12.2.1

>Solution :

Your constructors of the class Foo are declared with the function specifier explicit. So, you need to convert argument expressions explicitly to the type Foo to allow the function append() to bind them to the const lvalue reference.

As, for example:

instanceOfBar.append( Foo( 4 ) );

In fact, you are trying to do something like the following:

struct A { explicit A( int ) {} };
const A &a = 10;

This code will not compile because the compiler can not implicitly convert the integer constant 10 to the type A.

But, if you remove the function specifier explicit in the constructor declaration, then this code snippet will compile:

struct A { A( int ) {} };
const A &a = 10;

Leave a Reply