2016-11-15 21 views
2

Есть ли способ отключить операторы преобразования? Маркировка «= удалить» испортила другие вещи.Удаление операторов преобразования

Рассмотрим следующий код:

class Foo 
{ 
public: 

    Foo() :mValue(0) {} 
    ~Foo() = default; 
    Foo(int64_t v) { mValue = v; } 
    Foo(const Foo& src) = default; 

    bool operator==(const Foo& rhs) { return mValue == rhs.mValue; } 

    /* after commenting these lines the code will compile */ 
    operator int() const = delete; 
    operator int64_t() const = delete; 

private: 
    int64_t mValue; 
}; 

int main() 
{ 
    Foo foo1(5); 
    Foo foo2(10); 
    bool b1 = (foo1 == foo2); 
    bool b2 = (foo1 == 5); 
} 

Это не будет компилироваться, так как GCC жалуется, что оператор == неоднозначна:

test.cc: In function ‘int main()’: 
test.cc:25:21: error: ambiguous overload for ‘operator==’ (operand types are ‘Foo’ and ‘int’) 
    bool b2 = (foo1 == 5); 
        ^
test.cc:25:21: note: candidates are: 
test.cc:25:21: note: operator==(int, int) <built-in> 
test.cc:25:21: note: operator==(int64_t {aka long int}, int) <built-in> 
test.cc:10:10: note: bool Foo::operator==(const Foo&) 
    bool operator==(const Foo& rhs) { return mValue == rhs.mValue; } 
     ^

Однако, после того, как комментируя операторы преобразования, код легко компилировать и запускать.

Первый вопрос: почему операторы удаленного преобразования создают двусмысленность для оператора ==? Я думал, что они должны отключить неявные преобразования Foo -> int, но они, похоже, влияют на преобразования int -> Foo, которые не звучат логично для меня.

Второй: есть ли способ пометить, что операторы преобразования удалены? Да, не объявляя их, но я ищу способ, который каждый в будущем увидит, что эти преобразования отключены по дизайну.

+0

Возможный дубликат [Почему в разрешении перегрузки участвуют 11-удаленные функции C++?] (Http://stackoverflow.com/questions/14085620/why-do-c11-deleted-functions-participate-in-overload -разрешающая способность) – moooeeeep

ответ

2

Вот что я думаю, что это суть дела:

[dcl.fct.def.delete]:

программа, который ссылается на удаленную функцию неявно или явно, кроме как объявить ее, плохо сформирован.
...
Удаленная функция неявно является встроенной функцией ([dcl.inline]).

[class.member.lookup/4]:

Если С содержит объявление имени F, декларацию установить содержит каждую декларацию е объявленные в C, которая удовлетворяет требования от языка конструкции, в которой происходит поиск ,

Даже если вы delete функция, вы все равно заявляете об этом. И объявленная функция будет участвовать в разрешении перегрузки. Только когда это разрешенная перегрузка, компилятор проверяет, удалена ли она.

В вашем случае существует очевидная двусмысленность, когда эти объявления функций присутствуют.

3

Любое использование удаленной функции плохо сформировано (программа не будет составлять ).

Если функция перегружена, сначала выполняется разрешение перегрузки, и программа только плохо сформирована, если выбрана удаленная функция .

В вас случае программа не может выбрать преобразование becouse у вас есть 3 варианта

  • Int -> Foo

  • Foo -> Int

  • Foo -> int64

Второй q uestion: вы можете оставить его как есть, но всегда использовать явное преобразование для Int

bool b2 = (foo1 == Foo(5)); 

 Смежные вопросы

  • Нет связанных вопросов^_^