0

The istream operator>>'s require a reference to an existing object. That means what they do is assignment rather than in-place construction, right?

Well, how can I skip the initial construction? Maybe the compiler can optimize it away, but I may still be required to provide parameters I would rather not need to. Can this be done with istreams at all?

... I would like to be able to have, say,

template <typename T> void emplace_from(std::istream stream, T* place);

work for all types for T for which stream >> my_t_variable works. Although, admittedly, this function declaration looks a bit ugly.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Not with standard facilities AFAIK. Could you give an example of the syntax you wish to achieve ? – Quentin Apr 12 '16 at 14:55
  • The standard `emplace` calls a constructor. You pass constructor arguments to it, and it forwards them to the constructor. Your proposed `emplace` cannot construct anything because it has no idea how to extract constructor arguments out of a stream. It has no idea *which* constructor to use! – n. m. could be an AI Apr 12 '16 at 16:40

2 Answers2

2

This cannot be done with the extraction operator (std::istream& operator>>(std::istream&, T&)).

But with std::istream in general, sure. Simply, implement a function T extract(std::istream&) or similar instead. It can be implemented almost identically to the extraction operator: Read the character stream, initialize a new object using the input, return the object. Then you can simply call: T t = extract(std::cin).

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • "simply"... if I have implement that, I don't need istreams at all... :-( – einpoklum Apr 12 '16 at 15:21
  • 1
    @einpoklum i don't quite follow you. Why wouldn't you need istreams at all? – eerorika Apr 12 '16 at 15:28
  • using istreams lets me convert a string into any type (for which someone has bothered to implement operator>>). Without them, I need to implement conversions not just for the types I know of, but for whatever types my templated code will be used with ever in the future. – einpoklum Apr 12 '16 at 16:00
  • @einpoklum and analoguously, istreams let you convert a string to any type for which someone has bothered to implement `extract`. – eerorika Apr 12 '16 at 16:09
  • Yes, the thing is people know they should implement the extraction, but don't know they should implement my dreamt-up operation. – einpoklum Apr 12 '16 at 16:30
  • @einpoklum yes, being a standard convention is a significant advantage to the use of stream extreaction operator. But as I said, what you're asking for cannot be done with it. – eerorika Apr 12 '16 at 16:55
0
#include <experimental/optional>

namespace exp = std::experimental;

template<class T, class charT>
exp::optional<T> extract(std::basic_istream<charT>& is) {
    auto it = std::istream_iterator<T, charT>(is);
    if (it != decltype(it)()) {
        return *it;
    }
    return exp::optional<T>{};
}

int main()
{
    int i = *extract<int>(std::cin);
    std::cout << i;
}
David G
  • 94,763
  • 41
  • 167
  • 253
  • Note that this requires `T` to be default constructible, so it won't help in the case of `but I may still be required to provide parameters I would rather not need to` which I think implies that `T` is in fact, not default constructible. – eerorika Apr 13 '16 at 14:27
  • @user2079303 Then one should throw an exception or return nullptr. – David G Apr 13 '16 at 14:48