Неявные преобразования типов - ошибка компилятора - PullRequest
2 голосов
/ 20 августа 2010

Этот вопрос относится к этому вопросу. Следующий код компилирует прекрасный компилятор VC9, но выдает ошибку при компиляции с Comeau онлайн. Кто-нибудь может сказать мне, какой из них правильный и в чем смысл ошибки?

ошибка: неоднозначное "?" операция: вторая операнд типа "TypesafeBool" может быть преобразован в третий тип операнда "bool", и наоборот TypesafeBool b = (1 == 1)? f (): ложно;

class TypesafeBool
{
private:
    bool m_bValue;
    struct Bool_ { 
        int m_nValue; 
    };
    typedef int Bool_::* bool_;
    inline bool_ True() const { return &Bool_::m_nValue; }
    inline bool_ False() const { return 0; }

public:
    TypesafeBool( const bool bValue ) : m_bValue( bValue ){}
    operator bool_() const { return m_bValue ? True() : False(); }
};

TypesafeBool f()
{
    return TypesafeBool(true);
}

int main()
{
    TypesafeBool b = (1==1) ? f() : false;
}

Ответы [ 3 ]

10 голосов
/ 20 августа 2010

Ошибка в том, что троичный оператор должен иметь один тип, а выражение (1=1) ? f() : false имеет два типа - f() имеет тип TypesafeBool, а false имеет тип bool. Вы можете конвертировать между ними, но Comeau не знает, что вы хотите использовать. Чтобы решить эту проблему, приведите одну из сторон тройной к типу другой: (1=1) ? f() : TypesafeBool(false).

Comeau здесь правильно, поскольку для наблюдателя очевидно, какой тип должен принимать результат, троичное выражение должно иметь отдельный тип самостоятельно, без ссылки на то, в каком оно используется, и тип, который он должен выбрать: неоднозначный.

0 голосов
/ 20 августа 2010

Как следует из комментария @ hype, эта статья также выдвигает ту же идею, но с конструктором, помеченным explicit.Это устраняет вашу неоднозначность.

Обратите внимание, что ваш пример будет работать нормально, если вы измените инициализацию b на

TypesafeBool b( (1==1) ? f() : false );

, поскольку синтаксис = не позволяет вызывать TypesafeBool( bool ) когда он помечен как явный (потому что это технически композиция из двух конструкторов).

0 голосов
/ 20 августа 2010

Оба случая для оператора? результат должен иметь одинаковый тип. Естественный тип для них - TypesafeBool и bool. Поскольку существует неявное преобразование из bool в TypesafeBool и из bool в TypesafeBool, необходимо применить двусмысленность.

Правила C ++ предотвращают тот факт, что результат затем используется в контексте, где ожидается TypesafeBool, или тот факт, что результат, как известно, будет принят во внимание для предпочтения второго способа

TypesafeBool b = (1 == 1)? f() : TypesafeBool(false);

должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...