0

How would I create a function that can read values from a file into multiple numbers of variables varying from 1 to many?

Here's what I have so far, working from a similar question.

Note: I cannot use fold expressions (file >> ... >>> x) because the code uses C++ 14.

test_stream_file Contents:

teststring_a    teststring_b

Code:

template<typename... Args>
void fileread(std::fstream& file, Args...args)
{
    using expander = int[];
    expander{ (file >> (std::forward<Args>(args)), 0)... };
}

int main() {

    std::fstream teststream;
    teststream.open("test_stream_file", std::ios::in);
    std::string a, b;

    fileread(teststream, a, b);
    std::cout << a << b;
}

When I run this I get error C2679: "binary '>>': no operator found which takes a right hand operator of type '_Ty' (or there is no acceptable conversion)". I'm a bit lost here. I read the documentation and another answer on std::forward but am still not seeing what is going wrong.

wand_swe
  • 43
  • 5
  • 1
    I'm not knowledgeable enough to explain why, but you are missing universal reference on `Args` - it should be `Args&&... args)`: https://godbolt.org/z/GGao57YK9. I though your version (without `&&`) gets arguments by copy, but compiler states it's an r-value: https://godbolt.org/z/n5bKbq3dP – Yksisarvinen Apr 08 '22 at 15:01

2 Answers2

0

This is the working code for you:

#include<iostream>
#include<sstream>

template<typename... Args>
void fileread(std::istream& file, Args&...args)
{
    (file>> ...>>args);
}

int main() {

    std::stringstream teststream("hallo welt");
    //teststream.open("test_stream_file", std::ios::in);
    std::string a, b;

    fileread(teststream, a, b);
    std::cout << a << b;
}

Why do you try to do perfect forwarding, you want to change the variables that are given to you function, so it should be regular references.

gerum
  • 974
  • 1
  • 8
  • 21
  • The code I'm working in is the C++ 14 standard so it does not allow fold expressions. I cannot change this unfortunately. Have added this to the question. – wand_swe Apr 08 '22 at 16:25
  • If you can not use fold expressions then you can not use any syntax with "...". If you can not use fold expressions you must implement it recursive. – gerum Apr 09 '22 at 09:07
0

You don't have to use std::forward to forward args since they must be lvalue references. This should be enough

template<typename... Args>
void fileread(std::istream& file, Args&...args)
{
    using expander = int[];
    expander{ ((file >> args), 0)... };
}

Demo

康桓瑋
  • 33,481
  • 5
  • 40
  • 90