Как может преуспеть в более длинной неявной цепочке конверсии C ++, а строгое подразделение этого не удалось в поисках оC++

Программы на C++. Форум разработчиков
Ответить
Гость
 Как может преуспеть в более длинной неявной цепочке конверсии C ++, а строгое подразделение этого не удалось в поисках о

Сообщение Гость »

Фон
Наша первоначальная проблема заключалась в том, что включение 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 
, поскольку в цепочке есть только одно, определенное пользовательское преобразование. Но когда нет класса, ни одна из логики не будет запущена. Но я не нашел никакой поддержки для этого ни в каком эталонном материале. Например, оператор Microsoft перегрузка документации гласит: «Перегруженные операторы должны быть либо нестатической функцией члена класса, либо глобальной функцией. Глобальная функция, которая требует доступа к частным или защищенным членам класса, должна быть объявлена ​​как другом этого класса. Глобальная функция должна принимать хотя бы один аргумент, который имеет класс или перечисленный тип или который является ссылкой на класс или расширенный тип. Тип », кажется, постоянно используется. Я не могу найти никакой ссылки на то, что между ними есть разница. запуск всего этого. Кто -нибудь может объяснить, что происходит?

Подробнее здесь: https://stackoverflow.com/questions/797 ... ubchain-of
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»