我已经实现了无序地图容器和
copyIf
算法
template <class _InputIter, class _OutputIter, class _UnaryPred>
_OutputIter copyIf(_InputIter source_beg, _InputIter source_end,
_OutputIter dest_beg, _UnaryPred pred) {
while (source_beg != source_end) {
if (pred(*source_beg)) {
*dest_beg = *source_beg;
++dest_beg;
}
++source_beg;
}
return dest_beg;
}
我为我的容器实现了 ostream 类
template <class Pair, class CharT = char,
class Traits = std::char_traits<CharT>>
class map_ostream_iterator {
private:
std::basic_ostream<CharT, Traits> *m_stream;
const CharT *m_delimiter;
public:
map_ostream_iterator(std::basic_ostream<CharT, Traits> &stream,
const CharT *delimiter = "")
: m_stream(&stream), m_delimiter(delimiter) {}
map_ostream_iterator &operator=(const Pair &value) {
*m_stream << value.first << ": " << value.second << m_delimiter;
return *this;
}
map_ostream_iterator &operator*() { return *this; }
map_ostream_iterator &operator++() { return *this; }
map_ostream_iterator &operator++(int) { return *this; }
};
template <typename K, typename V>
std::ostream &operator<<(std::ostream &os, const std::pair<const K, V> &p) {
os << p.first << ": " << p.second;
return os;
}
我在
ostream
的 lambda 函数中使用了我的
Main.cpp
类
UnorderedMap<uint32_t, Goods> cont_3{
{101, {101, "laptop", "Dell", "New York, 5th Avenue, 15", 2.5}},
{202, {202, "smartphone", "Samsung", "Seoul, Samsung-ro, 67", 0.3}},
{303, {303, "tablet", "Apple", "Cupertino, Infinite Loop, 1", 0.6}},
{404, {404, "monitor", "LG", "Seoul, Yeouido-dong, 20", 4.8}},
{505, {505, "printer", "HP", "Palo Alto, Page Mill Road, 1501", 5.2}},
{606, {606, "router", "Cisco", "San Jose, Tasman Drive, 500", 0.7}},
{707, {707, "camera", "Canon", "Tokyo, Shimomaruko, 3", 0.9}},
{808, {808, "headphones", "Sony", "Tokyo, Konan, 1", 0.2}},
{909,
{909, "keyboard", "Logitech", "Lausanne, Innovation Park, 10", 1.1}},
{1010,
{1010, "mouse", "Razer", "San Francisco, Howard Street, 201", 0.1}}};
double weight_threshold = 1.0;
std::cout << "Items with weight greater than " << weight_threshold << ":"
<< std::endl;
std::ofstream out_file("Output.txt");
auto lambda = [](const PairType &pair) { return pair.second.m_weight > 1; };
copyIf(cont_3.begin(), cont_3.end(),
map_ostream_iterator<Goods>(out_file, " "), lambda);
out_file.close();
编译时出现以下错误:
In file included from Main.cpp:1:
Algorithms.h: In instantiation of ‘_OutputIter copyIf(_InputIter, _InputIter, _OutputIter, _UnaryPred) [with _InputIter = UnorderedMapIterator<unsigned int, Goods>; _OutputIter = map_ostream_iterator<Goods>; _UnaryPred = main()::<lambda(const PairType&)>]’:
Main.cpp:109:9: required from here
109 | copyIf(cont_3.begin(), cont_3.end(),
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110 | map_ostream_iterator<Goods>(out_file, " "), lambda);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Algorithms.h:123:17: error: no match for ‘operator=’ (operand types are ‘map_ostream_iterator<Goods>’ and ‘UnorderedMapIterator<unsigned int, Goods>::PairType’ {aka ‘std::pair<const unsigned int, Goods>’})
123 | *dest_beg = *source_beg;
| ~~~~~~~~~~^~~~~~~~~~~~~
In file included from Container.h:3,
from Algorithms.h:2:
Iterator.h:106:25: note: candidate: ‘map_ostream_iterator<Pair, CharT, Traits>& map_ostream_iterator<Pair, CharT, Traits>::operator=(const Pair&) [with Pair = Goods; CharT = char; Traits = std::char_traits<char>]’
106 | map_ostream_iterator &operator=(const Pair &value) {
| ^~~~~~~~
Iterator.h:106:47: note: no known conversion for argument 1 from ‘UnorderedMapIterator<unsigned int, Goods>::PairType’ {aka ‘std::pair<const unsigned int, Goods>’} to ‘const Goods&’
106 | map_ostream_iterator &operator=(const Pair &value) {
| ~~~~~~~~~~~~^~~~~
Iterator.h:96:7: note: candidate: ‘constexpr map_ostream_iterator<Goods>& map_ostream_iterator<Goods>::operator=(const map_ostream_iterator<Goods>&)’
96 | class map_ostream_iterator {
| ^~~~~~~~~~~~~~~~~~~~
Iterator.h:96:7: note: no known conversion for argument 1 from ‘UnorderedMapIterator<unsigned int, Goods>::PairType’ {aka ‘std::pair<const unsigned int, Goods>’} to ‘const map_ostream_iterator<Goods>&’
Iterator.h:96:7: note: candidate: ‘constexpr map_ostream_iterator<Goods>& map_ostream_iterator<Goods>::operator=(map_ostream_iterator<Goods>&&)’
Iterator.h:96:7: note: no known conversion for argument 1 from ‘UnorderedMapIterator<unsigned int, Goods>::PairType’ {aka ‘std::pair<const unsigned int, Goods>’} to ‘map_ostream_iterator<Goods>&&’
我不明白为什么如果声明并实现了operator=却找不到它。我认为也许值得重写
ostream
,以便它可以与任何容器和数据类型一起使用?
如果您阅读收到的错误消息,您就会看到问题:
Iterator.h:106:25: note: candidate: ‘map_ostream_iterator<Pair, CharT, Traits>& map_ostream_iterator<Pair, CharT, Traits>::operator=(const Pair&) [with Pair = Goods; CharT = char; Traits = std::char_traits<char>]’
106 | map_ostream_iterator &operator=(const Pair &value) {
| ^~~~~~~~
Iterator.h:106:47: note: no known conversion for argument 1 from ‘UnorderedMapIterator<unsigned int, Goods>::PairType’ {aka ‘std::pair<const unsigned int, Goods>’} to ‘const Goods&’
106 | map_ostream_iterator &operator=(const Pair &value) {
| ~~~~~~~~~~~~^~~~~
您的
map_ostream_iterator
的 operator=
采用类型为 named Pair
的参数,但它不是 actually Pair
- 它是 Goods
。
同时,传递给它的参数是
pair<unsigned int const, Goods>
。这可能是您希望用作参数的类型。
只需将模板参数向内移动 - 使其成为函数模板参数而不是类模板参数。为什么你的
map_ostream_iterator
类型需要知道 Pair
类型?
template <class Pair>
map_ostream_iterator& operator=(const Pair& value) {
*m_stream << value.first << ": " << value.second << m_delimiter;
return *this;
}
或者可以更具体一些
template <class K, class V>
map_ostream_iterator& operator=(const std::pair<K, V>& value) {
*m_stream << value.first << ": " << value.second << m_delimiter;
return *this;
}