Почему я получаю следующую ошибку: «нет соответствия для оператора ==»? (вложенный класс с шаблоном) - PullRequest
0 голосов
/ 25 июня 2018

Учитывая следующий код:

template<class T>
class TemplateClass {
    T val;
public:
    TemplateClass(T val) :
            val(val) {
    }
    TemplateClass(const TemplateClass& tc) = default;
    TemplateClass& operator=(const TemplateClass& tc) = default;

    class Ele {
        T x;
    public:
        Ele(T x) :
                x(x) {
        }
        template<class S>
        friend bool operator==(const typename TemplateClass<S>::Ele& e1,
                const typename TemplateClass<S>::Ele& e2);
    };
};

template<class T>
bool operator==(const typename TemplateClass<T>::Ele& e1,
        const typename TemplateClass<T>::Ele& e2) {
    return e1.x == e2.x;
}

int main() {
    TemplateClass<int>::Ele e1(4);
    TemplateClass<int>::Ele e2(3);
    if (e1 == e2) {  // *********** error
        std::cout << "ok" << std::endl;
    }
}  

Я получаю следующую ошибку:

нет соответствия для 'operator==' (типы операндов: 'TemplateClass<int>::Ele' и'TemplateClass<int>::Ele')

Может кто-нибудь сказать мне, как я могу это исправить и в чем проблема?

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

В дополнение к ответам здесь, вы можете использовать метод инъекции друга , чтобы исправить ошибку:

template<class T>
class TemplateClass {
    // ...
    class Ele {
        // ...
        friend bool operator==(const Ele& e1, const Ele& e2) {
            return e1.x == e2.x;
        }
    };
};

Обратите внимание, что вам не нужно проблематично typename TemplateClass<S>::Ele здесь вообще.

0 голосов
/ 25 июня 2018

Вложенное имя типа относится к не выводимым контекстам :

1) Спецификатор вложенного имени (все слева от оператора разрешения области: :) типа, указанного с помощью квалифицированного идентификатора:

Так что operator== не может быть вызвано, потому что не удается вывести аргументы шаблона; Параметр шаблона не может быть выведен.

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

template<class T>
class TemplateClass {
    ...
    class Ele {
        ...
        friend bool operator==(const typename TemplateClass<T>::Ele& e1,
                               const typename TemplateClass<T>::Ele& e2) {
            return e1.x == e2.x;
        }
    };
};

ЖИТЬ

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

template<class T>
class TemplateClass {
    ...
    class Ele {
        ...
        bool operator==(const typename TemplateClass<T>::Ele& e2) const;
        bool operator!=(const typename TemplateClass<T>::Ele& e2) const;
    };
};

template<class T>
bool TemplateClass<T>::Ele::operator==(const typename TemplateClass<T>::Ele& e2) const {
    return x == e2.x;
}
template<class T>
bool TemplateClass<T>::Ele::operator!=(const typename TemplateClass<T>::Ele& e2) const {
    return ! (*this == e2);
}

ЖИТЬ

...