为什么 clang 拒绝 gcc 接受的 unordered_set 定义?
Why does clang reject this unordered_set definition gcc accepts?
我想用我自己的哈希函数测试 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);
^
我不太明白这里的错误信息,你能帮忙告诉我如何修复我的代码吗?
您的比较运算符必须 const
合格:
bool operator == (const node& n) const {return value == n.value;}
^^^^^
通过将运算符实现为非成员函数,很容易避免此类错误。有关详细信息和最佳做法,请参阅 What are the basic rules and idioms for operator overloading?。
虽然 Baum mit Augen 已经告诉您问题所在,但我认为最好也解释一下如何从错误消息中找出更多信息。
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::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;}
^
"method is not marked const" 告诉你到底是什么问题。要修复它,就像 Baum mit Augen 的回答一样,标记方法 const
.
另一方面,如果答案是 "no, you are not supposed to be able to compare two const node
objects",那么问题就是 "why is unordered_set
comparing two const node
objects and how can I stop it"。为此,初始编译器消息的其余部分将告诉您哪些部分导致了该比较。你必须从上到下,在每一步都弄清楚 "is this supposed to work?" 如果是,弄清楚为什么它不起作用。如果不是,找出导致尝试的原因。
我想用我自己的哈希函数测试 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);
^
我不太明白这里的错误信息,你能帮忙告诉我如何修复我的代码吗?
您的比较运算符必须 const
合格:
bool operator == (const node& n) const {return value == n.value;}
^^^^^
通过将运算符实现为非成员函数,很容易避免此类错误。有关详细信息和最佳做法,请参阅 What are the basic rules and idioms for operator overloading?。
虽然 Baum mit Augen 已经告诉您问题所在,但我认为最好也解释一下如何从错误消息中找出更多信息。
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::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;} ^
"method is not marked const" 告诉你到底是什么问题。要修复它,就像 Baum mit Augen 的回答一样,标记方法 const
.
另一方面,如果答案是 "no, you are not supposed to be able to compare two const node
objects",那么问题就是 "why is unordered_set
comparing two const node
objects and how can I stop it"。为此,初始编译器消息的其余部分将告诉您哪些部分导致了该比较。你必须从上到下,在每一步都弄清楚 "is this supposed to work?" 如果是,弄清楚为什么它不起作用。如果不是,找出导致尝试的原因。