The subject is already touched in this boost-variant-ambiguous-construction question.
But my issue is not with types convertible to each other, but with completely unrelated types.
Simplified example:
// types not related in any way
class A {};
class B {};
class C {};
class D {};
using ABC_variant = boost::variant<A,B,C>;
using D_optional = boost::optional<D>;
The issue was related with the fact that optional on some type was not printable. But, completely unrelated output operator for some variant was trying to accept this boost::optional type (D_optional).
See:
std::ostream& operator << (std::ostream& os, const ABC_variant&)
{
return os << "ABC";
}
int main() {
D_optional dopt;
std::cout << dopt;
}
You can see on ideone - plenty of compilers errors saying that it does not know what do you want to print bool
or ABC_variant
and in case of ABC_variant
it does not know how to convert D_optional
to ABC_variant
. As I understand that boost::optional is convertible to bool
and first alternative is correct I have no idea why it tries to use ABC_variant
conversion...
Furthermore I simplified this example even more and give up with boost::optional:
int main() {
D d;
std::cout << d;
}
Now, it does not have "bool
alternative" and just complaining that it tries to construct ABC_variant
from D
:
prog.cpp:23:15: required from here /usr/include/boost/variant/variant.hpp:1591:38: error: no matching function for call to 'boost::variant::initializer::initialize(void*, D&)' initializer::initialize(
This here is ostream operator for ABC_variant
.
Of course I know that writing ostream operator for D/D_opt will solve the issue - but the problem is with diagnostic: if boost::variant did not accept any type as argument for its constructor, the compiler would tell me simple true - not this bunch of misleading sentences...
I doubt it is in such way by design - maybe there is some fixes ongoing?
Fortunately I and ideone uses the same compiler and boost: gcc4.9 and boost1.58.