2010-08-16 2 views
1

Что делать, если мне нужна другая работа, в зависимости от типа rval и lval? Определение нескольких перегрузок с ошибкой «operator = is неоднозначно».Перегрузка перегруженного оператора =?

Любые идеи или советы (ссылки на учебные пособия) очень ценятся, так как я только что узнал о перегрузке оператора.

Заранее благодарен!

EDIT:

Да, я хотел бы использовать C++ 0x, так как он у меня в наличии, просто я не вижу, как бы это влияние на код?

Это два случая, когда я использую его atm, если я получу его хорошо, lval отличается, поэтому они узнаваемы. Целью является преобразование в соответствующий тип.

int wrapint::operator=(int) 
{ 
    return m_iCurrentNumber; 
} 

void wrapint::operator=(const int& rhs) 
{ 
    m_iCurrentNumber = rhs; 
} 
+0

вы можете разместить код, с помощью которого вы получаете сообщение об ошибке? – Naveen

+1

с или без C++ 0x? – kennytm

+0

Можете ли вы разместить небольшой пример кода. Это неоднозначно, если нет точного соответствия для rval и возможно более одного преобразования. Значение lval должно быть точным. –

ответ

2

Для wrapint = wrapint ситуации:

wrapint& wrapint::operator=(const wrapint& rhs) 
{ 
    // test for equality of objects by equality of address in memory 
    // other options should be considered depending on specific requirements 
    if (this == &rhs) return *this; 

    m_iCurrentNumber = rhs.m_iCurrentNumber; 

    return *this; 
} 

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

Если вы хотите конвертировать из междунар в wrapint и наоборот, то вы должны обеспечить следующее:

1) от междунар до wrapint - правильный конструктор, который позволит неявное преобразование из INT; в качестве побочной записки вы должны действительно убедиться, что поведение предназначены и в проблемных сферах при работе с такими неявными преобразованиями (обратите внимание на явном ключевое слово С ++ для дальнейшего „просветления“)

2) из ​​wrapint в целое - правильный оператор литой

Ниже приведен пример:

#include <iostream> 

class wrapint 
{ 
public: 
    wrapint() : m_iCurrentNumber(0) 
    { 

    } 

    // allow implicit conversion from int 
    // beware of this kind of conversions in most situations 
    wrapint(int theInt) : m_iCurrentNumber(theInt) 
    { 

    } 

    wrapint(const wrapint& rhs) 
    { 
    if (this != &rhs) 
     this->m_iCurrentNumber = rhs.m_iCurrentNumber; 
    } 

    wrapint& operator=(const wrapint& rhs); 

    operator int() 
    { 
     return m_iCurrentNumber; 
    } 

private: 
    int m_iCurrentNumber; 
}; 

wrapint& wrapint::operator=(const wrapint& rhs) 
{ 
    // test for equality of objects by equality of address in memory 
    // other options should be considered depending on specific requirements 
    if (this == &rhs) return *this; 

    m_iCurrentNumber = rhs.m_iCurrentNumber; 
    return *this; 
} 

using namespace std; 

int main() 
{ 
    // this will be initialized to 0 
    wrapint theOne; 
    // this will be 15 
    wrapint theOtherOne = 15; 

    cout << "The one: " << theOne << "\n"; 
    cout << "The other one: " << theOtherOne << "\n"; 

    theOne = theOtherOne; 

    int foobar = theOne; 
    // all should be 15 
    cout << "The one: " << theOne << "\n"; 
    cout << "The other one: " << theOtherOne << "\n"; 
    cout << "The foobar: " << foobar << "\n"; 
    return 0; 
} 
+0

+1 После перечитывания вопроса примерно три раза я думаю, что это то, что происходит после OP. НО, пожалуйста, подумайте над добавлением примечания о том, что неявные преобразования, подобные этому, могут часто вызывать гораздо больше головных болей, чем они решают. –

+0

@ Марк Б отметил и действовал на :). Спасибо – celavek

+0

Обнаружил это раньше сегодня, все еще это покрывает ответ, спасибо! – Johnny

1

operator= предполагается изменить значение левого и значение левого должно быть типа класса. Возвращаемое значение (обычно *this) в основном игнорируется, за исключением случаев, когда вы назначаете назначения/другие вызовы функций (например, a = b = c;, где результат b = c присваивается a).

Если вы хотите, чтобы иметь возможность назначить wrapint на встроенный int, то это может быть достигнуто путем определения оператора произнесения на wrapint

wrapint::operator int() const { return m_iCurrentNumber; } 

Теперь wrapint будет неявно преобразован в междунар, когда вы пытаетесь присвоить его int.

int a; 
wrapint w; 
a = w; //== a = w.operator int() 
Смежные вопросы