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
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;