template<class T> struct CObject
{
CNexusObject * Object = nullptr;
CObject(){}
CObject(CNexusObject * o) : Object(o)
{
}
bool operator == (const CNexusObject * o) const
{
return Object && Object == o;
}
T * operator->()
{
return dynamic_cast<T *>(Object);
}
operator T * () const
{
return dynamic_cast<T *>(Object);
}
};
int main()
{
CObject<CNexusObject> a;
CNexusObject * b = nullptr;
if(a == b) // нужно чтобы вызывался мой оператор ==, вместо этого: error C2666: 'CObject<CNexusObject>::operator ==': 2 overloads have similar conversions
{
}
}
как разрулить?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
По сути вопроса: нужно просто вынести операторы сравнения за пределы класса, сделав их свободными функциями и предоставив все необходимые перегрузки.
Кроме того, хотелось бы обратить внимание на некоторые не очень хорошие моменты в коде: неявный преобразующий конструктор, неявный оператор преобразования к сырому указателю, открытый доступ к членам-данным. Ну и совсем мелочь — стиль именования членов-данных, затрудняющий чтение кода.
После исправления перечисленного, код мог бы выглядеть как-то так:
B>>int main()
B>>{
B>> CObject<CNexusObject> a;
B>> CNexusObject * b = nullptr;
B>> if(a == b) // error C2666: 'CObject<CNexusObject>::operator ==': 2 overloads have similar conversions
B>> {
B>> }
B>>}
B>>
LVV>Оба твоих объекта — не константные. LVV>А между тем, и метод у тебя константный, и параметр — константа.
Константные методы можно вызывать для неконстантных объектов — наоборот нельзя.
У него ведь проблема не в константности, а в неоднозначности — рассматриваемое сравнение можно выполнить двумя равноценными способами:
1) применить оператор сравнения, определенный в классе;
2) применить оператор неявного преобразования, после чего сравнить сырые указатели.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>У него ведь проблема не в константности, а в неоднозначности — рассматриваемое сравнение можно выполнить двумя равноценными способами: R>1) применить оператор сравнения, определенный в классе; R>2) применить оператор неявного преобразования, после чего сравнить сырые указатели.
а почему явный оператор не имеет приоритета? вроде логично
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, rg45, Вы писали:
R>Кроме того, хотелось бы обратить внимание на некоторые не очень хорошие моменты в коде: неявный преобразующий конструктор, неявный оператор преобразования к сырому указателю, открытый доступ к членам-данным. Ну и совсем мелочь — стиль именования членов-данных, затрудняющий чтение кода.
это всё хорошо, но это хорошо работает когда вам платят за время а не вы платите
к тому же 100500 get'ов в коде и явные касты там где и без них можно тоже читабельности не добавляют
что читатабельнее?
a == b
или
a.get() == (CObject *)b
Core->Manager
или
m_core.get()->get_manager()
у меня в таким стиле проекту уже 10 лет и никаких проблем о которых говорят теоретики у меня так и не возникло, например паблик мемберы никогда не создавали проблем изза своей публичности
и консты везде подряд тоже не нужны, такой стиль(перестраховка везде и всюду) нужен тока если у вас в команде индусы которые не могут понять, принять и следовать принятой идеологии, и их нада как детей от всего ограждать
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, Barbar1an, Вы писали:
B>это всё хорошо, но это хорошо работает когда вам платят за время а не вы платите B>к тому же 100500 get'ов в коде и явные касты там где и без них можно тоже читабельности не добавляют
B>что читатабельнее?
B>
Ну ты мой пример-то хоть посмотри. Где ты там видишь что-нибудь похожее на "a.get() == (CObject *)b"? Использование же осталось в точности как ты хочешь:
Здравствуйте, Barbar1an, Вы писали:
R>>У него ведь проблема не в константности, а в неоднозначности — рассматриваемое сравнение можно выполнить двумя равноценными способами: R>>1) применить оператор сравнения, определенный в классе; R>>2) применить оператор неявного преобразования, после чего сравнить сырые указатели.
B>а почему явный оператор не имеет приоритета? вроде логичноё
Я не знаю, на чем основаны твои ожидания, но о том, что неявные преобразования это зло, не говорил только ленивый за последние лет 20. И твой пример — еще одно подтверждение этому. Можешь посмотреть, например, это: C++ Coding Standards. 101 Rules, Guidelines, and Best Practices, рекомендация №40: "Avoid providing implicit conversions".
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Кроме того, хотелось бы обратить внимание на некоторые не очень хорошие моменты в коде: неявный преобразующий конструктор, неявный оператор преобразования к сырому указателю, открытый доступ к членам-данным. Ну и совсем мелочь — стиль именования членов-данных, затрудняющий чтение кода.
rg45, вы не заметили главного. Для кода
CObject<CNexusObject> a;
CNexusObject * b = nullptr;
условие
if(a == b)
{
}
никогда не выполняется
Ибо, согласно логике Barbar1an, нулевой указатель нулевому указателю не равен.
Здравствуйте, B0FEE664, Вы писали:
BFE>rg45, вы не заметили главного. Для кода BFE>никогда не выполняется BFE>Ибо, согласно логике Barbar1an, нулевой указатель нулевому указателю не равен.
Ну почему же, я заметил. Просто, даже включив все свое воображение, иначе, чем ошибку я это расценивать не могу. Причем, ошибку настолько не интересную, что даже не хочется заострять на ней внимание.
--
Не можешь достичь желаемого — пожелай достигнутого.
Получается ведь, что operator T * () const возвращает пойнтер на CNexusObject, и отсюда проблема с выбором operator ==.
Я бы предложил, что каждый объект должен сравнивать сам себя и убрал бы operator == из CObject и определил бы его в CNexusObject.