正如標題所說,我試圖使用包含Foo類對象的unordered_set作爲Foo類的數據成員。這在C++中可能嗎?unordered_set <Foo>作爲Foo的數據成員?
我有這樣的代碼:
#include <unordered_set>
using namespace std;
struct FooHash;
class Foo {
public:
int id;
unordered_set<Foo, FooHash> foos; // error here
bool operator==(const Foo& foo) {
return id == foo.id;
}
};
struct FooHash {
size_t operator()(const Foo& foo) const {
return foo.id;
}
};
int main() {
Foo f;
unordered_set<Foo, FooHash> foos;
return 0;
}
,但它引發以下錯誤:
In file included from /usr/include/c++/6.3.1/bits/hashtable.h:35:0,
from /usr/include/c++/6.3.1/unordered_set:47,
from main.cpp:1:
/usr/include/c++/6.3.1/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::__is_noexcept_hash<Foo, FooHash>’:
/usr/include/c++/6.3.1/type_traits:143:12: required from ‘struct std::__and_<std::__is_fast_hash<FooHash>, std::__detail::__is_noexcept_hash<Foo, FooHash> >’
/usr/include/c++/6.3.1/type_traits:154:38: required from ‘struct std::__not_<std::__and_<std::__is_fast_hash<FooHash>, std::__detail::__is_noexcept_hash<Foo, FooHash> > >’
/usr/include/c++/6.3.1/bits/unordered_set.h:95:63: required from ‘class std::unordered_set<Foo, FooHash>’
main.cpp:9:33: required from here
/usr/include/c++/6.3.1/bits/hashtable_policy.h:85:34: error: no match for call to ‘(const FooHash) (const Foo&)’
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/6.3.1/bits/move.h:57:0,
from /usr/include/c++/6.3.1/bits/stl_pair.h:59,
from /usr/include/c++/6.3.1/utility:70,
from /usr/include/c++/6.3.1/unordered_set:38,
from main.cpp:1:
/usr/include/c++/6.3.1/type_traits: In instantiation of ‘struct std::__not_<std::__and_<std::__is_fast_hash<FooHash>, std::__detail::__is_noexcept_hash<Foo, FooHash> > >’:
/usr/include/c++/6.3.1/bits/unordered_set.h:95:63: required from ‘class std::unordered_set<Foo, FooHash>’
main.cpp:9:33: required from here
/usr/include/c++/6.3.1/type_traits:154:38: error: ‘value’ is not a member of ‘std::__and_<std::__is_fast_hash<FooHash>, std::__detail::__is_noexcept_hash<Foo, FooHash> >’
: public integral_constant<bool, !_Pp::value>
正向聲明兩個類,並宣佈該方法給出了這兩個錯誤後:
In file included from /usr/include/c++/6.3.1/unordered_set:44:0,
from main.cpp:1:
/usr/include/c++/6.3.1/ext/aligned_buffer.h: In instantiation of ‘struct __gnu_cxx::__aligned_buffer<Foo>’:
/usr/include/c++/6.3.1/bits/hashtable_policy.h:246:43: required from ‘struct std::__detail::_Hash_node_value_base<Foo>’
/usr/include/c++/6.3.1/bits/hashtable_policy.h:277:12: required from ‘struct std::__detail::_Hash_node<Foo, true>’
/usr/include/c++/6.3.1/bits/hashtable_policy.h:1894:60: required from ‘struct std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<Foo, true> > >’
/usr/include/c++/6.3.1/bits/hashtable.h:170:11: required from ‘class std::_Hashtable<Foo, Foo, std::allocator<Foo>, std::__detail::_Identity, std::equal_to<Foo>, FooHash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, true, true> >’
/usr/include/c++/6.3.1/bits/unordered_set.h:96:18: required from ‘class std::unordered_set<Foo, FooHash>’
main.cpp:12:37: required from here
/usr/include/c++/6.3.1/ext/aligned_buffer.h:85:34: error: invalid application of ‘sizeof’ to incomplete type ‘Foo’
: std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>
^
/usr/include/c++/6.3.1/ext/aligned_buffer.h:85:34: error: invalid application of ‘sizeof’ to incomplete type ‘Foo’
/usr/include/c++/6.3.1/ext/aligned_buffer.h: In instantiation of ‘void* __gnu_cxx::__aligned_buffer<_Tp>::_M_addr() [with _Tp = Foo]’:
/usr/include/c++/6.3.1/ext/aligned_buffer.h:110:41: required from ‘_Tp* __gnu_cxx::__aligned_buffer<_Tp>::_M_ptr() [with _Tp = Foo]’
/usr/include/c++/6.3.1/bits/hashtable_policy.h:250:34: required from ‘_Value* std::__detail::_Hash_node_value_base<_Value>::_M_valptr() [with _Value = Foo]’
/usr/include/c++/6.3.1/bits/hashtable_policy.h:1971:36: required from ‘void std::__detail::_Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type*) [with _NodeAlloc = std::allocator<std::__detail::_Hash_node<Foo, true> >; std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type = std::__detail::_Hash_node<Foo, true>]’
/usr/include/c++/6.3.1/bits/hashtable_policy.h:1984:22: required from ‘void std::__detail::_Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type*) [with _NodeAlloc = std::allocator<std::__detail::_Hash_node<Foo, true> >; std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type = std::__detail::_Hash_node<Foo, true>]’
/usr/include/c++/6.3.1/bits/hashtable.h:1901:7: required from ‘void std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::clear() [with _Key = Foo; _Value = Foo; _Alloc = std::allocator<Foo>; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<Foo>; _H1 = FooHash; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, true, true>]’
/usr/include/c++/6.3.1/bits/hashtable.h:1227:12: required from ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::~_Hashtable() [with _Key = Foo; _Value = Foo; _Alloc = std::allocator<Foo>; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<Foo>; _H1 = FooHash; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, true, true>]’
/usr/include/c++/6.3.1/bits/unordered_set.h:126:7: required from here
/usr/include/c++/6.3.1/ext/aligned_buffer.h:99:36: error: using invalid field ‘__gnu_cxx::__aligned_buffer<_Tp>::_M_storage’
return static_cast<void*>(&_M_storage);
看來標準中不允許使用不完整類型的容器。我想嘗試使用指針,但不能爲指針操作數重載operator==
。任何解決方法?
順便說一句,不知道這是不是嚴格UB有'不完全類型的unordered_set'。 – Jarod42
@FrançoisAndrieux修正,謝謝。 – devil0150