6
\$\begingroup\$

For some time it has been bothering me that there is apparently no way to directly initialize variables from input streams (something like int i << std::cin;)

My solution is this:

#include <iostream>
#include <iomanip>
#include <string>

template<class T>
T get(std::istream& in){
    T tmp;
    in >> tmp;
    return tmp;
}

template<class T,class A, class... ARGS>
T get(std::istream& in, A& arg, ARGS&... args){
    in >> arg;
    return get<T>(in, args...);
}

int main() {
    int i = get<int>(std::cin);
    std::cout << i << std::endl;

    std::string s = get<std::string>(std::cin , std::setw(5));
    std::cout << s << std::endl;
}

I'd like to know if

  • I can improve something on the design
  • There are serious performance implications
  • There are corner cases where this will not work or even worse produce silent errors.
  • I've overlooked any standard functions/classes that already implement that functionality.
\$\endgroup\$
1
  • \$\begingroup\$ Worth looking at boost::lexical_cast<> \$\endgroup\$ Commented Apr 11, 2015 at 3:51

1 Answer 1

4
\$\begingroup\$

There are corner cases where this will not work or even worse produce silent errors.

The function as it is, depends on the client to check for errors on the stream (either by calling std::cin.exceptions(std::ifstream::failbit); or by checking the stream state, after the call to get).

Ideally, I would want to write:

if(auto a = get<int>(std::cin))
    // use a here

Maybe you could add something like this to your solution:

template<class T>
boost::optional<T> get_optional(std::istream& in){
    T tmp;
    in >> tmp;
    return (in) ?
        boost::optional<T>{ std::move(tmp) } :
        boost::optional<T>{};
}
\$\endgroup\$
3
  • \$\begingroup\$ One could also use expected as a kind of enhanced optional to return information about the potential errors. \$\endgroup\$
    – Morwenn
    Commented Apr 9, 2015 at 14:19
  • \$\begingroup\$ Thanks for the suggestion, I'll add that version to my toolbox. To that end: do you know the status of std::optional or whether it is allowed to just copy boost implementation into my own source code? For such small tools I try not to introduce any dependencies to 3rd Party libraries (although boost is included in a lot of my projects anyway). \$\endgroup\$
    – MikeMB
    Commented Apr 9, 2015 at 16:43
  • \$\begingroup\$ As far as I know, boost.optional is header only. There is a tool in the boost package for extracting all dependencies, per library. \$\endgroup\$
    – utnapistim
    Commented Apr 9, 2015 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.