【问题标题】:Trouble overloading extraction operator for custom PriorityQueue为自定义 PriorityQueue 重载提取运算符时遇到问题
【发布时间】:2016-06-30 01:24:43
【问题描述】:

我正在尝试为我一直在编写的自定义 PriorityQueue 类重载 operator>>,代码如下:

/**
 * @brief Overloaded stream extraction operator.
 *
 * Bitshift operator>>, i.e. extraction operator. Used to write data from an input stream
 * into a targeted priority queue instance. The data is written into the queue in the format,
 *
 * \verbatim
 [item1] + "\t" + [priority1] + "\n"
 [item2] + "\t" + [priority2] + "\n"
 ...
 * \endverbatim
 *
 * @todo Implement functionality for any generic Type and PriorityType.
 * @warning Only works for primitives as template types currently!
 * @param inStream Reference to input stream
 * @param targetQueue Instance of priority queue to manipulate with extraction stream
 * @return Reference to input stream containing target queue data
 */
template<typename Type, typename PriorityType> std::istream& operator>>(std::istream& inStream, PriorityQueue<Type, PriorityType>& targetQueue) {

    // vector container for input storage
    std::vector< std::pair<Type, PriorityType> > pairVec;
    // cache to store line input from stream
    std::string input;

    std::getline(inStream, input);

    if (typeid(inStream) == typeid(std::ifstream)) {
        inStream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    // loop until empty line
    while (!input.empty()) {
        unsigned int first = 0;
        // loop over input cache
        for (unsigned int i = 0; i < input.size(); ++i) {
            // if char at index i of cache is a tab, break from loop
            if (input.at(i) == '\t')
                break;
            ++first;
        }
        std::string data_str = input.substr(0, first);
        // convert from std::string to reqd Type
        Type data = atoi(data_str.c_str());

        std::string priority_str = input.substr(first);
        // convert from std::string to reqd PriorityType
        PriorityType priority = atof(priority_str.c_str());

        pairVec.push_back(std::make_pair(data, priority));

        // get line from input stream and store in input string
        std::getline(inStream, input);
    }

    // enqueue pairVec container into targetQueue
    //targetQueue.enqueueWithPriority(pairVec);

    return inStream;

}

这目前适用于stdinstd::cin 输入,但它不适用于fstream 输入 - 第一个getline 总是从输入中读取一个空行,因此while 循环永远不会得到触发了,我似乎无法跳过它(我尝试使用inStream.ignore(),如您在上面看到的,但这不起作用。

编辑:

目前我只是想让它适用于文件输入,而忽略它目前仅适用于 int 数据类型和 double 优先级类型的事实 - 这些不相关(@ 987654333@ 对象本身)。

目前我只关心在尝试通过文件输入流式传输时解决空白行问题。

要传递的示例文件:

3    5.6
2    6.3
1    56.7
12   45.1

每行上的数字以\t 分隔。

示例测试:

#include "PriorityQueue.h"
#include <sstream>
#include <iostream>
#include <fstream>

int main(void) {

    // create pq of MAX binary heap type
    PriorityQueue<int, double> pq(MAX);


    std::ifstream file("test.txt");

    file >> pq;

    std::cout << pq;

}

其中“test.txt”是上面示例文件的格式。

编辑:更简单的示例

代码:

#include <iostream>
#include <fstream>
#include <vector>

class Example {

public:

    Example() {}

    size_t getSize() const { return vec.size(); }

    friend std::istream& operator>>(std::istream& is, Example& example);

private:

    std::vector< std::pair<int, double> > vec;

};

std::istream& operator>>(std::istream& is, Example& example) {

    int x;
    double y;
    while (is >> x >> y) {
        std::cout << "in-loop" << std::endl;
        example.vec.push_back(std::make_pair(x, y));
    }
    return is;
}

int main(void) {

    Example example;

    std::ifstream file("test.txt");

    file >> example;

    file.close();

    std::cout << example.getSize() << std::endl;

    return 0;

}

【问题讨论】:

  • 请提供minimal reproducible example。您可能需要阅读哪些示例文件内容?
  • @Barry 事实上,我现在已经向 OP 添加了一个编辑 - 重新迭代队列的实际操作在这里并不重要,我只想知道如何解决空行从文件输入流中读取时出现问题。
  • 这是 minimal 的一部分。只需删除代码中所有不相关的内容,并显示一个无法执行您想要的操作的示例文件。
  • 如何在while循环之前添加一个额外的getline到一些临时字符串中,然后为input执行实际的getline

标签: c++ operator-overloading data-stream extraction-operator


【解决方案1】:

对于许多类型,操作符已经被重载——并且应该被重载。让这些功能发挥作用:

template<typename Type, typename PriorityType>
std::istream& operator>>(std::istream& inStream, PriorityQueue<Type, PriorityType>& targetQueue)
{
  std::vector< std::pair<Type, PriorityType> > pairVec;
  Type data;
  PriorityType priority;

  while(inStream >> data >> priority)
    pairVec.push_back(std::make_pair(data, priority));

  targetQueue.enqueueWithPriority(pairVec);

  return inStream;
}

【讨论】:

  • 适用于 stdinstd::cin 但这似乎仍然不适用于文件流:/
  • @ArchbishopOfBanterbury:真的吗?我用文件流测试了它,它工作得很好。如果您发布minimal complete example,也许我们可以解决。
  • 也许我是个白痴,忘记了如何正确归档流,但我现在将测试代码从我的main 发送到 OP
  • @ArchbishopOfBanterbury:这仍然不是一个完整的例子。你确定pairVec 没有任何内容?
  • @ArchbishopOfBanterbury:为我工作:in-loopin-loopin-loopin-loop4 这是一个最小的例子?也就是说,如果进一步简化,错误会消失,文件 I/O 是否开始工作?
猜你喜欢
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 1970-01-01
相关资源
最近更新 更多