C ++ Range-v3:尝试将转换链接在一起

时间:2019-05-24 03:49:03

标签: c++ c++17 range-v3

我对范围库是完全陌生的,所以我不会为这段代码没有编译而感到惊讶,也无法弄清原因:

#include <iostream>
#include <algorithm>
#include <fstream>
#include <iterator>
#include <vector>

#include <range/v3/all.hpp>
#include <range/v3/view/all.hpp>
using namespace ranges::v3;


std::ifstream open_file(const std::string &filename) {
    return std::ifstream{filename};
}

int count_lines(std::ifstream &in) {
    return std::count(std::istreambuf_iterator<char>{in},
                      std::istreambuf_iterator<char>{}, '\n');
}

std::vector<int>
count_lines_in_files(const std::vector<std::string> &filenames) {
    auto a1 = filenames | view::transform(open_file) | view::transform(count_lines);
    return a1;
}

int main() {
    const std::vector<std::string> files{"listing1_1.cpp",
                                         "listing1_2.cpp",
                                         "listing1_4.cpp",
                                         "listing1_5.cpp"};
    const auto result = count_lines_in_files(files);
    std::cout << ranges::view::all(result) << '\n';
}

看来投诉是关于a1的,编译器告诉我“错误:变量的类型为'void'不完整。”

有人可以看到我在做什么错吗,或者告诉我如何尽可能地将它们正确地链接在一起?

谢谢!

2 个答案:

答案 0 :(得分:3)

Porsche9II所述,“ std::ifstream没有副本构造函数”。您可以在此处找到有关此主题的更多信息:

Why are iostreams not copyable?

C ++ 11为std::basic_ifstream引入了移动构造函数(6),因此您可以编写

auto open_file(const std::string &filename) {
    return std::ifstream{filename};
}

auto count_lines(std::ifstream &&in) {
    return std::count(std::istreambuf_iterator<char>{in},
                      std::istreambuf_iterator<char>{}, '\n');
}

可测试的HERE

答案 1 :(得分:2)

std::ifstream没有副本构造函数-通过函数返回std::ifstream并不是一个好主意。一种可能的解决方案:打开和计数应该在一个函数中进行。