I came across an elegant line of reading a binary file into a vector like this (that works):
std::ifstream ifs("myfile.bin", std::ios::binary);
std::vector<char> buffer(std::istreambuf_iterator<char>(ifs), {});
Instead since I want my vector to be a shared pointer I write:
std::ifstream ifs("myfile.bin", std::ios::binary);
auto sp = std::make_shared<std::vector<char>>(std::istreambuf_iterator<char>(ifs), {});
I.e just pass the vector constructor arguments to make_shared (as I usually do to create any shared pointer of any objects). But I get: error: no matching function for call to 'make_shared'?
Detailed output:
/usr/include/c++/11.1.0/bits/shared_ptr.h|873 col 5| note: candidate template ignored: substitution failure [with _Tp = std::vector<char, std::allocator>]: deduced incomplete pack <std::istreambuf_iterator<char, std::char_traits >, (no value)> for template parameter '_Args' || make_shared(_Args&&... __args)
This will work:
std::ifstream ifs("myfile.bin", std::ios::binary);
auto sp = std::make_shared<std::vector<char>>(std::istreambuf_iterator<char>(ifs),
std::istreambuf_iterator<char>{});
This is because you are using this variadic template:
template<class T, class... Args>
shared_ptr<T> make_shared( Args&&... args );
where every single argument type must be deducable, if not manually instantited. '{}' doesn't allow for argument deduction, hence the compiler error. That being sad, you can also explicitly instantiate the template:
auto sp = std::make_shared<std::vector<char>, std::istreambuf_iterator<char>,
std::istreambuf_iterator<char>>({ifs}, {});
In both cases, a type alias for the iterator might improve readability (using InputIt = std::istreambuf_iterator<char>;
or something along those lines).