Тема затронута в этом boost-variant-ambiguous-construction question.boost :: вариант строения странности - его cтор принимает все
Но моя проблема не в том, что типы конвертируются друг в друга, но с совершенно несвязанными типами.
Упрощенный пример:
// 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>;
Проблема была связана с тем, что дополнительно на какой-то тип не был для печати. Но совершенно не связанный оператор вывода для некоторого варианта пытался принять этот boost :: optional type (D_optional).
См:
std::ostream& operator << (std::ostream& os, const ABC_variant&)
{
return os << "ABC";
}
int main() {
D_optional dopt;
std::cout << dopt;
}
Вы можете увидеть на ideone - множество компиляторов ошибок, говоря, что он не знает, что вы хотите напечатать bool
или ABC_variant
и в случае ABC_variant
он не знает, как конвертировать D_optional
- ABC_variant
. Насколько я понимаю, boost :: optional конвертируется в bool
, и первая альтернатива верна. Я понятия не имею, почему она пытается использовать ABC_variant
конверсии ...
Кроме того, я упростил этот пример еще больше и отказался от boost :: optional :
int main() {
D d;
std::cout << d;
}
Теперь он не имеет "bool
альтернативы" и просто жалуются, что он пытается построить ABC_variant
из 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(
Th здесь является оператором ostream для ABC_variant
.
Конечно, я знаю, что запись операционного оператора для D/D_opt решит проблему, но проблема связана с диагностикой: если boost :: variant не принимал никакого типа в качестве аргумента для своего конструктора, компилятор скажет мне просто true - не эта куча вводящих в заблуждение предложений ...
Я сомневаюсь, что это так по дизайну - возможно, некоторые исправления продолжаются?
К счастью, я и идеон используют один и тот же компилятор и boost: gcc4.9 и boost1.58.
'optional' только * контекстуально * конвертируется в 'bool'. Что касается 'variant', этот конструктор должен быть ограничен, но это не так. –