将自定义比较器重载到 std::map
Overload custom comparator to std::map
我正在尝试解决 this problem。我想到了这个解决方案:
typedef unordered_map<string, double> stockDictType;
class StockTicker {
class Comparator {
public:
inline bool operator() (const string &a, const string &b) const {
return stocksDict.at(a) < stocksDict.at(b);
}
};
stockDictType stocksDict;
map<string, stockDictType::iterator, Comparator> stocksTicker; // this is where I need a custom comparator method
int tickerSize;
public:
StockTicker(int k): tickerSize(k) {}
// some other methods
};
很明显,编译失败:StockTicker::stocksDict
不是静态成员。现在我不能这样做,因为我可能需要 StockTicker
class 的多个实例。
std::map
使用严格的比较器函数参数定义(std::map
只会传入要比较的键),所以我不能重载它来传递对当前实例的引用StockTicker
class(我本可以通过 public getter 访问 StockTicker::stocksDict
)
我从 and the 中得到灵感来做这个:
typedef unordered_map<string, double> stockDictType;
class StockTicker {
class Comparator {
public:
stockDictType &_stockDictRef;
explicit Comparator(stockDictType &stocksDict): _stockDictRef(stocksDict) {}
inline bool operator() (const string &a, const string &b) const {
return _stockDictRef.at(a) < _stockDictRef.at(b);
}
};
stockDictType stocksDict;
map<string, stockDictType::iterator, Comparator> stocksTicker(Comparator{stocksDict});
int tickerSize;
public:
StockTicker(int k): tickerSize(k) {}
void addOrUpdate(string name, double price) {
stocksDict[name] = price;
stocksTicker.at(name) = stocksDict.find(name);
}
vector<stockDictType::iterator> top() {
vector<stockDictType::iterator> ret(tickerSize);
auto it = stocksTicker.begin();
for(int i = 0; i < tickerSize; i++, it++)
ret[i] = it->second;
return ret;
}
};
这也不会编译。我在 StockTicker::addOrUpdate()
和 StockTicker::top()
方法中得到这个 kind of error :
error: '((StockTicker*)this)->StockTicker::stocksTicker' does not have class type
.
我也尝试了很多其他的东西(比如在 StockTicker
class 本身中声明一个 public 比较器方法,并试图将它的函数指针传递给 std::map
。那也失败了;StockTicker::stocksTicker
在比较器方法声明之前被声明,编译器抱怨)。
关于如何解决这个问题有什么想法吗?
std::map<std::string, stockDictType::iterator, Comparator> stocksTicker(Comparator(stocksDict));
这定义了一个名为 stocksTicker
的成员函数,它接受一个 stocksDict
类型的参数 Comparator
和 returns 一个 std::map
.
std::map<std::string, stockDictType::iterator, Comparator> stocksTicker{Comparator{stocksDict}};
这定义了一个成员变量stocksTicker
,默认情况下,它用Comparator
初始化,而Comparator
又用成员变量stocksDict
.
初始化
我假设你想要第二个。
你的语法介于两者之间。无论您对此感到困惑的编译器是什么。
您应该 StockTicker(StockTicker &&)=delete
和 StockTicker& operator=(StockTicker &&)=delete
,因为包含对其 class 的引用的地图移动或复制是不安全的。
在这里生成有效的移动是很棘手的。我怀疑 C++17 节点拼接可能使它成为可能。您可能必须嵌入一个 std::shared_ptr<stocksDict*>
(是的,一个指向指针的共享指针),并使用 .key_comp
重新设置目标中的 stocksDict
。
我正在尝试解决 this problem。我想到了这个解决方案:
typedef unordered_map<string, double> stockDictType;
class StockTicker {
class Comparator {
public:
inline bool operator() (const string &a, const string &b) const {
return stocksDict.at(a) < stocksDict.at(b);
}
};
stockDictType stocksDict;
map<string, stockDictType::iterator, Comparator> stocksTicker; // this is where I need a custom comparator method
int tickerSize;
public:
StockTicker(int k): tickerSize(k) {}
// some other methods
};
很明显,编译失败:StockTicker::stocksDict
不是静态成员。现在我不能这样做,因为我可能需要 StockTicker
class 的多个实例。
std::map
使用严格的比较器函数参数定义(std::map
只会传入要比较的键),所以我不能重载它来传递对当前实例的引用StockTicker
class(我本可以通过 public getter 访问 StockTicker::stocksDict
)
我从
typedef unordered_map<string, double> stockDictType;
class StockTicker {
class Comparator {
public:
stockDictType &_stockDictRef;
explicit Comparator(stockDictType &stocksDict): _stockDictRef(stocksDict) {}
inline bool operator() (const string &a, const string &b) const {
return _stockDictRef.at(a) < _stockDictRef.at(b);
}
};
stockDictType stocksDict;
map<string, stockDictType::iterator, Comparator> stocksTicker(Comparator{stocksDict});
int tickerSize;
public:
StockTicker(int k): tickerSize(k) {}
void addOrUpdate(string name, double price) {
stocksDict[name] = price;
stocksTicker.at(name) = stocksDict.find(name);
}
vector<stockDictType::iterator> top() {
vector<stockDictType::iterator> ret(tickerSize);
auto it = stocksTicker.begin();
for(int i = 0; i < tickerSize; i++, it++)
ret[i] = it->second;
return ret;
}
};
这也不会编译。我在 StockTicker::addOrUpdate()
和 StockTicker::top()
方法中得到这个 kind of error :
error: '((StockTicker*)this)->StockTicker::stocksTicker' does not have class type
.
我也尝试了很多其他的东西(比如在 StockTicker
class 本身中声明一个 public 比较器方法,并试图将它的函数指针传递给 std::map
。那也失败了;StockTicker::stocksTicker
在比较器方法声明之前被声明,编译器抱怨)。
关于如何解决这个问题有什么想法吗?
std::map<std::string, stockDictType::iterator, Comparator> stocksTicker(Comparator(stocksDict));
这定义了一个名为 stocksTicker
的成员函数,它接受一个 stocksDict
类型的参数 Comparator
和 returns 一个 std::map
.
std::map<std::string, stockDictType::iterator, Comparator> stocksTicker{Comparator{stocksDict}};
这定义了一个成员变量stocksTicker
,默认情况下,它用Comparator
初始化,而Comparator
又用成员变量stocksDict
.
我假设你想要第二个。
你的语法介于两者之间。无论您对此感到困惑的编译器是什么。
您应该 StockTicker(StockTicker &&)=delete
和 StockTicker& operator=(StockTicker &&)=delete
,因为包含对其 class 的引用的地图移动或复制是不安全的。
在这里生成有效的移动是很棘手的。我怀疑 C++17 节点拼接可能使它成为可能。您可能必须嵌入一个 std::shared_ptr<stocksDict*>
(是的,一个指向指针的共享指针),并使用 .key_comp
重新设置目标中的 stocksDict
。