Наша первоначальная проблема заключалась в том, что включение Boost :: logic :: tribool вызвало выражение формы ReferenceToclass! = nullptr для счастливо скомпилировать. В конечном итоге мы отслеживаем это до неявной цепочки преобразования classtype => anenum (пользователь определяют) => bool с левой стороны, и nullptr_t => boost :: logic :: indeterminate на правой стороне, вызывая оператор! /> Наше исследование проблемы было замедлено с помощью явления, которое я до сих пор не могу объяснить. Мы думали, что неявное преобразование в перечисление может быть виновником, поэтому мы попытались собрать выражение формы Anenum! Это заставило нас сделать вывод, что это неявное преобразование не может быть причиной. В конце концов, если использование enum напрямую не компилируется, как может быть преобразование в перечисление, вызвать его компиляцию? Но после изучения других возможностей мы смогли определить, что это действительно так. Цепочка преобразования класс => enum => bool совпадает с оператором, но enum => bool нет, несмотря на то, что он является суффиксом первого.
Код: Выделить всё
enum LegacyEnum {
One,
Two
};
class Convertible {
public:
// The operator only matches when the left operand has
// an implicit conversion to an enum.
operator LegacyEnum() const {
return One;
}
};
// At least one of the operator operands must have a class or enumeration type.
// This class is just to make the operator valid.
class ImplicitCreatable {
public:
// Allow implicit creation from nullptr.
ImplicitCreatable(decltype(nullptr)) {}
};
// This operator somehow matches (Convertible, nullptr),
// but does not match (LegacyEnum, nullptr).
bool operator!=(bool, ImplicitCreatable)
{ return false; }
int main()
{
Convertible conv;
// This compiles because Convertible can be user-converted to LegacyEnum,
// which can be standard-converted to bool.
if( conv != nullptr ) {
return 1;
}
// But somehow an expression that already has type LegacyEnum
// does not match the operator.
LegacyEnum enumerable = One;
if( enumerable != nullptr ) { // error : invalid operands to binary expression ('LegacyEnum' and 'std::nullptr_t')
return 3;
}
return 0;
}
< /code>
cppinsight < /p>
как MSVC, так и Clang дают аналогичную ошибку. Я получил предложение, что перечисление вообще не запускает машины по поиску перегрузки оператора. Механизм, когда-то запускаемый присутствием класса, может затем следовать за цепью вплоть до Bool Подробнее здесь: https://stackoverflow.com/questions/797 ... ubchain-of
Мобильная версия