I'm looking at a wrapping class, based on https://www.fluentcpp.com/category/strong-types/ The main difference is that I'm replacing the get()
method with a explicit casting operator as this triggers questions during code review when used.
As you can see in the simplified code below, I have 3 overloads of the casting operator:
- From
const A &
toint
- From
A &&
toint
- From
const A &
toconst int &
When writing: static_cast<int>(a)
, I expect the overload of const A &
to int
to be used. However, it seems to favor the int
and the const int &
overload equally. Why does it do so?
Similarly to this, it seems to allow const int &r = static_cast<const int &>(createA());
which I assume is a life-time bug. (assuming createA returns an A by value)
Simplified code at Compiler Explorer: https://gcc.godbolt.org/z/YMH9Ed
#include <utility>
struct A
{
int v = 42;
explicit operator int() const & { return v; } // Removing this line works
explicit operator int() && { return std::move(v); }
explicit operator const int &() const & { return v; }
};
int main(int, char**)
{
A a;
int r = static_cast<int>(a);
return r;
}
Compilation error:
<source>:14:13: error: ambiguous conversion for static_cast from 'A' to 'int'
int r = static_cast<int>(a);
^~~~~~~~~~~~~~~~~~~
<source>:6:14: note: candidate function
explicit operator int() const & { return v; }
^
<source>:8:14: note: candidate function
explicit operator const int &() const & { return v; }
^