majintao0131 / yaml-cpp

Automatically exported from code.google.com/p/yaml-cpp
MIT License
0 stars 0 forks source link

support for an alternative to C++ stream style methods to read values from a Node. #31

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
C++ style stream operators can look neat, but are really not very convenient at 
times.
An improvised example:
{{{
#!c++
Coord Coord::create (YAML::Node& node) {
  double x, y;
  node["x"] >> x;
  node["y"] >> y;
  return Coord (x,y);
}

// couldn't we instead write the following and avoid those temporary variables?
Coord Coord::create (YAML::Node& node) {
  return Coord (node["x"].read<double>(), node["y"].read<double>());
}
}}}

It should be really easy to implement:
{{{
    template <typename T>
    inline T Node::read () const {
        T value;
        if(!Read(value))
            throw InvalidScalar(m_mark);
    }
}}}
Feel free to rename it of course, "read" is just a convenient name but doesn't 
really fit
with the naming scheme (and "Read" would conflict). Perhaps "Scalar".

That it has to be templated is annoying, but we can't overload functions by 
return type
(why, I never quite figured out...). Anyway, implementing this (as a template) 
looks
fairly consistent and is a nice alternative to ">>".

And thanks; other  than this little niggle yaml-cpp is a really nice 
easy-to-use library!
(Btw I also created a templated method to read a node into a std::vector. Are 
you
interested in adding code like this to the library?)

Original issue reported on code.google.com by diggory....@gmail.com on 18 Aug 2009 at 10:01

GoogleCodeExporter commented 9 years ago
Sounds good! I just committed it (r220) - it's called `Read()` also - there's no
problem with the other `Read`, since those accept an output parameter. Also, I
implemented it using `operator >>`, so it should work for any type that 
overloads
that function, including any user-defined ones. (Of course, if you're using 
`Read` to
do this, then you probably don't want to implement `operator >>` :)

Also, w.r.t. an overload for `std::vector`, I don't really want to, because:

1) it's pretty easy to implement if you actually want it, and
2) any time you're creating large things (like a big ol' vector), people may 
have
different opinions about how to manage the memory, etc., so I don't want to get 
into
that.

I'm glad you like the library, and thanks for the suggestion! 

Original comment by jbe...@gmail.com on 19 Aug 2009 at 3:41

GoogleCodeExporter commented 9 years ago
Thanks for the fast additions!

Btw I couldn't work out why the following code didn't work earlier. It's 
inconsequential to me (it was
inherently inefficient anyway), but as far as I can tell it should work:
{{{
void operator>> (const YAML::Node& node, vector<T>& vec) {
  vec.resize (node.size());
  for (size_t i = 0; i < node.size(); ++i) {
    cout << "iteartion: " << i<<endl;
    node[i] >> vec[i];  // yaml-cpp: error at line 0, column 0: bad dereference
  }

  // This does work nicely:
  /*size_t i = 0;
  for (YAML::Iterator it = node.begin(); it != node.end(); ++it, ++i) {
    vec[i] = it->Read<double>();
  }*/
}
}}}

Original comment by diggory....@gmail.com on 19 Aug 2009 at 6:57

GoogleCodeExporter commented 9 years ago
This was an interesting fix! The reason your initial code didn't work is that I 
only
overloaded `int` and `unsigned` for indexing sequences, not `std::size_t`. In 
the
latest commit (r222), it now should accept any index type (the list, right now, 
is
`std::size_t, int, unsigned, short, unsigned short, long, unsigned long`), so 
that
code should work fine.

Original comment by jbe...@gmail.com on 19 Aug 2009 at 9:00