Почему clang отклоняет это определение unordered_set, которое принимает gcc? - PullRequest
0 голосов
/ 25 августа 2018

Я хочу проверить unordered_set с моей собственной хэш-функцией:

#include<unordered_set>
#include<iostream>
#include<functional>
using namespace std;
struct node{
    size_t value;
    bool operator == (const node& n){return value == n.value;}
};
size_t h(const node& n){
    return n.value;
}
int main(){
    unordered_set<node, std::function<size_t(const node&)>> s2(3,h);//failed
    return 0;
}

Я пытался скомпилировать его, в то время как clang выдает огромное количество ошибок:

clang++ m.cpp -std=c++11
In file included from m.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_set:324:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:659:21: error: invalid operands to binary
    expression ('const node' and 'const node')
        {return __x == __y;}
                ~~~ ^  ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2175:32: note: in instantiation of member
    function 'std::__1::equal_to<node>::operator()' requested here
                            key_eq()(__cp->__value_, __np->__next_->__value_);
                            ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2121:9: note: in instantiation of member function
    'std::__1::__hash_table<node, std::__1::function<unsigned long (const node &)>, std::__1::equal_to<node>, std::__1::allocator<node> >::__rehash' requested here
        __rehash(__n);
        ^

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

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Хотя Баум мит Ауген уже говорил вам о проблеме, я думаю, что это хорошая идея, чтобы объяснить, как вы могли бы узнать больше из сообщения об ошибке.

clang++ m.cpp -std=c++11
<strong>In file included from m.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_set:324:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:659:21: error: invalid operands to binary
    expression ('const node' and 'const node')
        {return __x == __y;}
                ~~~ ^  ~~~</strong>
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2175:32: note: in instantiation of member
    function 'std::__1::equal_to::operator()' requested here
                            key_eq()(__cp->__value_, __np->__next_->__value_);
                            ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2121:9: note: in instantiation of member function
    'std::__1::__hash_table, std::__1::equal_to, std::__1::allocator >::__rehash' requested here
        __rehash(__n);
        ^

Эта первая часть говорит вам, чтопри сравнении const node с другим const node произошла ошибка.На этом этапе вам нужно будет принять собственное суждение, чтобы определить, сможете ли вы сравнить два const node с.

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

#include<cstddef>
using namespace std;
struct node{
    size_t value;
    bool operator == (const node& n){return value == n.value;}
};
int main(){
    const node a{}, b{};
    a == b;
}

Если вы попытаетесь скомпилировать это, clang дастВы более подробно:

error: invalid operands to binary expression ('const node' and 'const node')
        a == b;
        ~ ^  ~
note: candidate function not viable: 'this' argument has type 'const node', but method is not marked const
        bool operator == (const node& n){return value == n.value;}
             ^

«метод не помечен как const» точно говорит вам, в чем проблема.Чтобы исправить это, как в ответе Баума мит Аугена, отметьте метод const.

Если, с другой стороны, ответ был бы «нет, вы не должны иметь возможность сравнивать два const node объектов ", тогда возникает вопрос" почему unordered_set сравнивает два const node объекта и как я могу это остановить ".Для этого остальная часть исходного сообщения компилятора скажет вам, какие части вызывают это сравнение.Вам придется идти сверху вниз, выясняя на каждом шагу "это должно работать?"Если это так, выясните, почему это не работает.Если это не так, выясните, что является причиной попытки.

0 голосов
/ 25 августа 2018

Ваш оператор сравнения должен быть const квалифицирован:

bool operator == (const node& n) const {return value == n.value;}
                                 ^^^^^

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

...