сбой при перегрузке функции:почему эти операторы столкнулись?

StackOverflow https://stackoverflow.com/questions/211376

Вопрос

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

Движок определяет класс vector3 как typedef другого класса vector3 с операторами равенства, которые находятся в пространстве имен engine, а не в классе vector3.Я добавил класс в приложение, у которого также были операторы равенства в пространстве имен приложения.

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

// engine.h
namespace Engine
{
    class Vector3Impl { ... };
    typedef Vector3Impl Vector3;
    bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }
}


// myfile.cpp
#include "engine.h"

namespace application
{
    class MyClass { ... };
    bool operator==(MyClass const &lhs, MyClass const &rhs) { ... }

    void myFunc(...)
    {
        if ( myClassA == myClassB ) { ... } // builds
    }

    void anotherFunc(...)
    {
        Engine::Vector3 a, b;
        ...
        if ( a == b ) { ... } // fails
    }
}

Однако, подумав об этом, я не могу понять, почему компиляция завершилась неудачей.Нет никаких неявных преобразований из vector3s в мой класс или наоборот, и поиск, зависящий от аргумента, должен извлекать оператор равенства из пространства имен engine и сопоставлять его.

Я пытался воспроизвести эту ошибку в примере проекта на C ++, но она отказывается ломаться.В большой базе кода должно быть что-то, вызывающее эту проблему, но я не уверен, с чего начать поиск.Что-то вроде противоположности мошенническому "использованию движка"?У кого-нибудь есть какие-нибудь идеи?

Это было полезно?

Решение

Стандарт C ++, 3.4.4.2 объявляет:

Для каждого аргумента типа T в вызове функции существует набор из нуля или более связанных пространств имен и набор из нуля или более связанных классов, которые необходимо учитывать.Наборы пространств имен и классов полностью определяются типами аргументов функции (и пространства имен любого аргумента шаблона template). Имена Typedef и объявления using используемые для указания типов, не влияют на этот набор.

ADL не работает с typedef.

Другие советы

Однажды я столкнулся с такой же проблемой с компилятором, у которого не было поиска, зависящего от аргумента (поиск по Кенигу - спасибо @igor) (я думаю, VC6).Это означает, что когда он видит оператор, он просто заглядывает во окружающие пространства имен.

Итак, не могли бы вы рассказать нам, какой компилятор вы используете?

Переход на другой компилятор решил эту проблему.

Действительно, очень неудобно.

bool operator==(Vector3 const &lhs, Vector3 const &rhs) { ... }

Каноническое определение оператора равенства, определенного в классе, должно иметь только один аргумент, а именно rhs.LHS - это вот что.Однако не знаю, будет ли это решением вашей проблемы.

Это то, что я бы написал :

класс Vector3 { оператор bool==( const Vector3 & rhs) const { ...} };

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top