這是一個錯誤,還是我做錯了什么?我已經嘗試為指標型別提供散列和相等仿函式,但它似乎不起作用。我什至嘗試創建自己的微型模板容器來測驗仿函式。
哈希仿函式:
class CharPtHash
{
private:
using pChar = char*;
public:
size_t operator()(const pChar& c) const
{
std::hash<char> hasher;
if (c == nullptr)
{
return 0;
}
return hasher(*c);
}
};
平等:
class CharPtEqual
{
private:
using pChar = char*;
public:
bool operator()(const pChar& lhs, const pChar& rhs)const
{
if (lhs == rhs)//not sure of nullptr is equal to itself.
{
return true;
}
else if (lhs==nullptr || rhs==nullptr)
{
return false;
}
return *lhs == *rhs;
}
};
主要的:
int main()
{
cout << "Testing unordered_multiset with keys being simple types:\n";
unordered_multiset<char> sA1({ 'a','b','c' });
unordered_multiset<char> sA2({ 'a','c','b' });
cout << "Values: " << endl << sA1 << endl << sA2 << endl;
cout << (sA1 == sA2 ? "Equal" : "Not Equal");
cout << endl;
cout << "Testing unordered_multiset with keys being pointers to simple types:\n";
char** c1 = new char* [3]{ new char('a'), new char('b'), new char('c') };
char** c2 = new char* [3]{ new char('a'), new char('c'), new char('b') };
unordered_multiset<char*,CharPtHash,CharPtEqual> sB1;
unordered_multiset<char*,CharPtHash,CharPtEqual> sB2;
sB1.insert(c1[0]);
sB1.insert(c1[1]);
sB1.insert(c1[2]);
sB2.insert(c2[0]);
sB2.insert(c2[1]);
sB2.insert(c2[2]);
cout << "Values: " << endl << sB1 << endl << sB2 << endl;
cout << (sB1 == sB2 ? "Equal" : "Not Equal");
cout << endl;
cin.get();
}
我嘗試使用 Visual Studio 2022 將其編譯為 c 20 和 c 14。
這是輸出:
Testing unordered_multiset with keys being simple types:
Values:
{ a, b, c }
{ a, c, b }
Equal
Testing unordered_multiset with keys being pointers to simple types:
Values:
{ a, b, c }
{ a, c, b }
Not Equal
uj5u.com熱心網友回復:
好吧,我之前的回答是完全錯誤的:據我所知,您的Hash和Pred是正確的。但是,問題出在其他地方。operator ==forstd::unordered_multiset用于std::is_permutation()在內部執行比較并且不提供該演算法的任何比較函式,因此使用operator ==該型別的默認值(在本例中char*)。因為我認為有 UB,但我真的不明白那里的措辭。
公平地說,這看起來像是對標準的疏忽。operator ==forstd::unordered_multimap不允許比較不同型別的映射,因此應該可以將Pred實體傳遞給std::is_permutation. 或者也許有這樣的理由,但我看不到。
uj5u.com熱心網友回復:
提供你自己的KeyEqual只會在內部改變行為,即插入新專案。不過對 . 沒有影響operator==。
根據operator==( std::unordered_multiset),它的行為就好像每個等價物equal_ranges 都與 進行了比較std::is_permutation。
您可以潛在地std::is_permutation為您設定的 C 20 之前的行為專門化(這是自 C 20 以來未定義的行為):
template<>
bool std::is_permutation(
std::unordered_multiset<char*, CharPtHash, CharPtEqual>::const_iterator l_begin,
std::unordered_multiset<char*, CharPtHash, CharPtEqual>::const_iterator l_end,
std::unordered_multiset<char*, CharPtHash, CharPtEqual>::const_iterator r_begin)
{
return std::is_permutation(l_begin, l_end, r_begin, CharPtEqual{});
}
或者只是char*用自定義的operator==.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/534644.html
