2016-01-15 3 views
3

Я реализовал следующий класс, который обертывает общий указатель.Устранение неоднозначной перегрузки оператора

class Wrapper 
{ 
    private: 
    std::shared_ptr<const MyClass> mPointer; 

    public: 
    Wrapper(MyClass* myClass); 

    operator bool(void) const; 

    const MyClass* operator*(void) const; 

    const MyClass* operator->(void) const; 

    Wrapper operator!(void) const;  

    Wrapper operator||(Wrapper rhs) const; 

    Wrapper operator&&(Wrapper rhs) const; 
}; 

Объект класса Wrapper сам должен вести себя как логическое, чтобы иметь возможность написать:

Wrapper Wrapper_A = Wrapper(new MyClass(true)); 
Wrapper Wrapper_B = Wrapper(new MyClass(false)); 

if(Wrapper_A && Wrapper_B) {} 

Теперь рассмотрим следующую функцию:

void WrapperHandler::add(Wrapper wrapper); 

Если эта функция использовались следующим образом:

add(Wrapper_A); 

или

add(!Wrapper_A); 

проблем не возникает.

Но когда я пишу

add(Wrapper_A || Wrapper_B); 

следующее сообщение об ошибке компиляции происходит (VS 2010):

Error 1 error C2664: 'WrapperHandler::add' : cannot convert parameter 1 from 'bool' to 'Wrapper' 

Если я перегрузить оператор || следующим образом (чтобы скрыть встроенный оператор):

Wrapper operator||(const Wrapper& rhs) const; 

ошибка возникает все же.

Следующие строки работают правильно:

bool test = Wrapper_A || Wrapper_B; 

Почему результат оператора || всегда бросать на bool?

Большое спасибо заранее

+4

Во-первых, вы должны извлечь минимальный пример в соответствии с рекомендациями проводки. Затем рассмотрим использование операторов, не являющихся членами, по крайней мере для двоичных операторов. –

+0

Думаю, вы задаете неправильный вопрос. – erip

+0

Visual Studio 2010 не поддерживает функции C11. Я удивлен, что вы вообще могли использовать 'shared_ptr'. –

ответ

4

Почему результат оператора || всегда приводится к BOOL?

Это не так, в соответствии со спецификацией (http://en.cppreference.com/w/cpp/language/operators):

от указанных выше ограничений, язык не ставит никаких других ограничений на то, что делают перегруженные операторы, или тип возвращаемого

Это случай, когда приоритет оператора не является тем, что вы ожидаете.

Вы этот перекрытый оператор:

operator bool(void) const; 

Это означает, что, когда это возможно, компилятор попытается преобразовать объект в bool.Когда компилятор встречает это:

add(Wrapper_A || Wrapper_B); 

Это преобразование как Wrapper_A и Wrapper_B к bool и затем запуска || оператора на результат этого преобразования.

Для решения проблемы убедитесь, что оператор bool отмечен как explicit, что автоматически прекратит это преобразование.

explicit operator bool(void) const; 
+0

Явное ключевое слово, вероятно, сделает это, но, к сожалению, явные операторы не поддерживаются в VS2010. – Randir