2017-02-21 37 views
3

У меня проблемы с перегрузкой оператора ==, разные ошибки компилятора с использованием VC++ (2015) и g ++ 5.4.0 (-std == C++ 14). Вот код (это только экстракт более сложной ситуации в моей реальной базе кода):Проблемы с перегрузкой оператора == подкатегория шаблона

#include <vector> 

template<typename T> 
struct A { 
    struct B { 
     std::vector<T> _elements; 

     // Internal cmp op. 
     bool operator==(const B &other) { 
      return _elements == other._elements; 
     } 
    }; 

    std::vector<B> _entries; 
}; 

// External cmp op. 
template<typename T> 
inline bool operator==(typename const A<T>::B &l, typename const A<T>::B & r) { 
    return l._elements == r._elements; 
} 

int main() { 
    A<int>::B b0, b1; 

    b0.operator==(b1);       // a 
    operator==<int>(b0, b1);      // b 
    b0 == b1;          // c 

    std::vector<A<int>::B> v0, v1; 

    std::equal(v0.begin(), v0.end(), v1.begin()); // d 
    v0 == v1;          // e 

    return 0; 
} 

я не добавлять сообщения об ошибках, потому что у меня немецкая версия VC++ и г ошибки ++ по многим линиям.

VC++ дает сообщение об ошибке (e). Я не понимаю, почему, потому что вектор <> :: operator ==, кажется, вызывает std :: equal внутри и (d) компилирует штраф. Почему это не удается?

g ++ не может принять мой внешний оператор ==(), поэтому полностью не удается скомпилировать этот короткий код. Я понятия не имею, как написать внешний оператор ==() для A <T> :: B, который работает с обоими компиляторами.

Я еще не пробовал clang.

Большое спасибо.

+0

«У меня есть немецкая версия VC++ и ошибки g ++ на многих строках». Английские обычно не намного лучше. – user4581301

ответ

3

Существовали две ошибки в программе:

// Internal cmp op. 
    bool operator==(const B &other) const { 
            ///// <- here 
     return _elements == other._elements; 
    } 

должен быть const членом и ключевое слово const не может появиться только за typename:

// External cmp op. 
template<typename T> 
inline bool operator==(typename A<T>::B const& lhs, typename A<T>::B const& rhs) 
             ///// <-   here -> //// 
{ 
    return lhs._elements == rhs._elements; 
} 

Live Example

Обратите внимание, что размещение const обычно довольно либерально на C++, например вы можете написать как const typename A<T>::B & lhs, так и typename A<T>::B const& lhs, но форма, которую вы выбрали, typename const A<T>::B & lhs не допускается.

Также обратите внимание, что вы хотите написать либо член operator==, либо не являющийся членом operator==, но оба они оба. В вашем случае, потому что Tis not deducible в typename A<T>::B, вы должны написать уродливый operator==<int>(b0, b1), чтобы выбрать не члена.

Я хотел бы удалить шаблон, не являющемуся членом operator== и добавить в шаблон класса A<T> не-членов

bool operator==(const A &other) const { 
    return _entries == other._entries;  
} 

, так что вы можете также сравнить объекты из A<int>. Обратите внимание, что это вызовет стандартную библиотеку operator== для std::vector, которая, в свою очередь, вызовет ваш operator== для B.

+0

Большое спасибо, это помогает для обеих проблем. Константа для версии участника была просто что-то, что я забыл в извлеченном коде. Но я никогда не думал, что неуместная константа может создать так много разных ошибок. Сообщения об ошибках g ++ упоминали что-то о const, но я этого не понимал. Теперь это немного более ясно, и я должен понять это подробно, спасибо снова. –

+1

@ hob-B1T, пожалуйста, используйте кнопку «принять» – TemplateRex

+0

Третья ошибка заключается в том, что этот шаблон оператора никогда не будет использоваться. –