无序映射中ostream的麻烦[关闭]

问题描述 投票:0回答:1

我已经实现了无序地图容器和

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
,以便它可以与任何容器和数据类型一起使用?

c++ c++20 unordered-map ofstream ostream
1个回答
-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) {
      |                                   ~~~~~~~~~~~~^~~~~

您的

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.