重载operator ==模板子类的问题

时间:2017-02-21 20:25:23

标签: c++ templates operator-overloading const-correctness

我在使用VC ++(2015)和g ++ 5.4.0(--std == c ++ 14)重载operator ==,不同的编译器错误时遇到了问题。这是代码(这只是我真实代码库中更复杂情况的摘录):

#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 ++的德语版本,g ++错误跨越多行。

VC ++在(e)上给出错误。我不明白为什么,因为vector&lt;&gt; :: operator ==似乎在内部调用std :: equal而且(d)编译得很好。为什么这会失败?

g ++无法接受我的外部运算符==(),因此完全无法编译此短代码。我不知道如何编写适用于两个编译器的A&lt; T&gt; :: B的外部运算符==()。

我还没有尝试过铿锵声。

非常感谢。

1 个答案:

答案 0 :(得分:3)

您的计划中有两个错误:

    in dataconfig.xml:
    <entity name="artist" query="SELECT artist_id, name, email, total_jobs, created FROM artist_list">
    <field column="artist_id" template="ARTIST_${artist.artist_id}" name="id"/>        
    <field column="created" name="artist_created" />
    </entity> 

    in schema.xml:
    <fieldType name="tdate" class="solr.TrieDoubleField" omitNorms="true" />
    <field name="artist_created" type="tdate" indexed="false" stored="true"/>

应该是 // Internal cmp op. bool operator==(const B &other) const { ///// <- here return _elements == other._elements; } 成员,关键字const不能出现在const后面:

typename

Live Example

请注意,// 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; } 的位置在C ++中通常相当宽松,例如您可以同时撰写constconst typename A<T>::B & lhs,但您选择的表单不允许typename A<T>::B const& lhs

另请注意,您要写一个成员typename const A<T>::B & lhs或非成员operator==,但不要同时写两个。在您的情况下,因为operator==中的T is 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