模拟流进行测试

时间:2018-11-19 19:58:17

标签: c++ stream

Get an istream from a char*开始,我正在尝试为一些测试编写一个模拟流容器,如下所示:

eg_data2 <- data.frame(
ID = c(1,1,1,1,1,1,1,1,1,1) , 
date = c('20181101','20181101','20181101','20181101','20181101','20181101','20181101','20181101','20181101','20181101') , 
start = c("12:05","13:55","15:00","16:40","18:15", "18:50", "19:40", "20:20", "21:00", "22:15") ,
stop =  c("13:10","14:40","15:30","17:30","18:45", "19:20", "20:05", "20:50", "21:30", "22:55") ,
diff_stp1_sta2 = c(NA,45,20,70,45,5,20,15,10,45))

,其用法如下:

@IBAction func addArticle(_ sender: UIButton) {
    numItems += 1
    let indexPath = IndexPath(row: numItems - 1, section: 0)
    myTableView.beginUpdates()
    myTableView.insertRows(at: [indexPath], with: .automatic)
    myTableView.endUpdates()
    view.endEditing(true)
}

@objc func removeArticle(sender: UIButton) {
    numItems -= 1
    let indexPath = IndexPath(row: sender.tag, section: 0)
    myTableView.beginUpdates()
    myTableView.deleteRows(at: [indexPath], with: .automatic)
    myTableView.endUpdates()
}

上面的代码只是我尝试过的内容(这里是link),并且存在错误提示-关于如何正确有效地实现此建议?

P.S。根据要求,以上代码当前引发以下编译错误:

extension MyViewController: UITableViewDataSource, UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return numItems
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        numItems -= 1
        self.myTableView.beginUpdates()
        self.myTableView.deleteRows(at: [indexPath], with: .automatic)
        self.myTableView.endUpdates()
    }
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if firstUse{
        firstUse = false
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyTableViewCell

    if firstUse{
        //setting cell
        //...
        cell.name.isEnabled = false
        cell.name.textColor = UIColor.gray
        cell.unit.text = //something
    }

    return initCell(cell: cell, indexPath: indexPath)
}

func initCell(cell: MyTableViewCell, indexPath: IndexPath) -> MyTableViewCell {
    cell.name.inputAccessoryView = addDoneToolbarKeyboard()
    cell.amount.inputAccessoryView = addDoneToolbarKeyboard()

    cell.name.filterStrings(getFilteredBy())
    cell.minusButton.tag = indexPath.row
    cell.minusButton.addTarget(self, action: #selector(self.removeArticle), for: .touchUpInside)
    cell.name.itemSelectionHandler = { filteredResults, itemPosition in
        //irrelevant code
        }
    }

    return cell
}

编辑: 感谢@Martin York的回答,我进行了较小的更改就能解决此问题:将m_body转换为指针而不是引用。

1 个答案:

答案 0 :(得分:1)

您的成员变量m_body是引用:

std::istream&    m_body;
            ^     reference

因此,您试图通过在构造函数中创建一个临时实例来初始化此引用。

explicit MockStreamContainer(char* buffer, int offset, int nbytes):
    m_sbuf(buffer + offset, buffer + offset + nbytes),
    m_body(&m_sbuf),    // Here you are passing a pointer to `std::streambuf`
                        // This is not an `std::istream` so the compiler
                        // is trying to create one using the single argument
                        // constructor.
                        //
                        // That worked. So you have a temporary `std::istream` object
                        //
                        // You can not bind a temporary object to a non const reference
                        // hence the compiler error.
    m_size(nbytes)
{}

我会这样做:

#include <iostream>

struct mock_membuf : public std::streambuf
{
    mock_membuf(char* begin, char* end) {
        this->setg(begin, begin, end);
    }
};

struct mock_stream: public std::istream
{
    mock_membuf     streamBuffer;
    public:
        mock_stream(char* buffer, int offset, int nbytes)
            : std::istream(nullptr)
            , streamBuffer(buffer + offset, buffer + offset + nbytes)
        {
            rdbuf(&streamBuffer);
        }
};

int main()
{
    char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";

    std::string line;
    mock_stream in(buffer, 5, 10);
    while (std::getline(in, line)) {
        std::cout << "line: " << line << "\n";
    }
    return 0;
}