Defining custom input types for the new yaml-cpp API

我是研究僧i 提交于 2019-12-24 07:58:02

问题


I am trying to define some custom input types using the new-style YamlCpp API. I have two questions. Let me first say that we are currently using the 0.3 style-api and everything works great. The code-appearance of the new API is about 10x better though so we wanted to move to it.

  1. Why does my current approach bork the compiler?
  2. Is yaml-cpp smart enough to handle nested templates. For example, if my parser knows how to enc/dec std::vectors, and then I define a custom handler for MyAwesomeType separately -- can I ask it to enc/dec a std::vector<MyAwesomeType> and it will figure it out?

My code began by copying and pasting the example on the website (here) and then modifying that. My current implementation attempts to handle conversion of std::vector<std::pair<qint16,qint16>> -- this does not compile. (fyi - qint16 is simply a cross-platform typedef for __int16)

#include "yaml-cpp\yaml.h"
#include <vector>
#include "qglobal.h"

namespace YAML {
   // a std::pair of qint16's
   template<>
   struct convert<std::pair<qint16,qint16>> {
      static Node encode( std::pair<qint16,qint16> const& rhs) {
         Node node;
         std::vector<qint16> newVec;
         newVec.push_back(rhs.first);
         newVec.push_back(rhs.second);
         node = newVec;
         return node;
      }
      static bool decode(Node const& node, std::pair<qint16,qint16> & rhs) {
         if(!node.IsSequence() || node.size() != 2) {
            return false;
         }

         rhs.first = node[0].as<qint16>();
         rhs.second = node[1].as<qint16>();
         return true;
      }
   };

   // a vector of std::pair of qint16's
   template<>
   struct convert<std::vector<std::pair<qint16,qint16>>> {
      static Node encode( std::vector<std::pair<qint16,qint16>> const& rhs) {
         Node node;
         for(auto pairIt=rhs.begin();pairIt!=rhs.end();++pairIt)
         {
             node.push_back( *pairIt );
         }
         return node;
      }
      static bool decode(Node const& node, std::vector<std::pair<qint16,qint16>> & rhs) {
         if( !node.IsSequence() ) {
            return false;
         }

         for(int k=0;k<node.size();++k)
         {
             rhs.push_back( node[k].as<std::pair<qint16,qint16>>() );
         }
         return true;
      }
   };
}

Finally, I would like to then use this to call

std::map<std::string, std::vector<std::pair<qint16, qint16>>> m_vectorOfPairs;
if( doc["myPairs"] )
{
    // key exists!
    for( YAML::const_iterator it=doc["myPairs"].begin();it!=doc["myPairs"].end();++it)
    {
        m_vectorOfPairs[it->first.as<std::string>()] = it->second.as<std::vector<std::pair<qint16,qint16>>>();
    }
}

...based on input yaml which looks like this...

myPairs:
  pairOne: [[4, 25], [48, 336]]
  pairTwo: [[4, 25], [57, 336]]
  pairThree: [[4, 25], [48, 336]]

The compiler error output from this is about 300 lines, so I will not post that here. Platform: Visual Studio 2010 SP1 x64

Thanks for your help.

EDIT: Here is the first of many errors I get, namely that it doesn't even seem happy parsing a Node key with the new style... I'm adding this because what is causing this may be related to the other errors.
Code

YAML::Node doc = YAML::LoadFile(buildFilenamePath(m_spectCameraShortName, relativePath).toStdString());
    if( doc["numPixels"] )
....

Causes

1>ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/impl.h(146): error C2734: 'lhs' : const object must be initialized if not extern
1>          ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/impl.h(96) : see reference to function template instantiation 'bool YAML::detail::node_data::equals<const char[10]>(YAML::detail::node &,T (&),YAML::detail::shared_memory_holder)' being compiled
1>          with
1>          [
1>              T=const char [10]
1>          ]
1>          ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/node_ref.h(52) : see reference to function template instantiation 'YAML::detail::node &YAML::detail::node_data::get<const char[10]>(Key (&),YAML::detail::shared_memory_holder)' being compiled
1>          with
1>          [
1>              Key=const char [10]
1>          ]
1>          ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/detail/node.h(103) : see reference to function template instantiation 'YAML::detail::node &YAML::detail::node_ref::get<const char[10]>(Key (&),YAML::detail::shared_memory_holder)' being compiled
1>          with
1>          [
1>              Key=const char [10]
1>          ]
1>          ANONPATH\thirdparty\yaml-cpp\include\yaml-cpp/node/impl.h(333) : see reference to function template instantiation 'YAML::detail::node &YAML::detail::node::get<const char[10]>(Key (&),YAML::detail::shared_memory_holder)' being compiled
1>          with
1>          [
1>              Key=const char [10]
1>          ]
1>          MYCODEFILE.cpp(75) : see reference to function template instantiation 'YAML::Node YAML::Node::operator []<const char[10]>(Key (&))' being compiled
1>          with
1>          [
1>              Key=const char [10]
1>          ]

Note that the Line 75 mentioned in the error above is the

if( doc["numPixels"] ) 

line I've recompiled from source latest using Rev 573 of default branch and all these examples are from that code.


回答1:


Yes, yaml-cpp should be able to handle nested templates (and so you shouldn't need to define a conversion for std::vector<std::pair<qint16, qint16>> - and, this suggests that yaml-cpp should define a conversion for std::pair<T, U> in general (http://code.google.com/p/yaml-cpp/issues/detail?id=188)).

And I'm not sure why the compiler doesn't accept your code (it looks correct, and compiles fine on Linux for me).

Do the tests compile at all? Apparently, 0.5.0 doesn't work out of the box on Visual Studio (see http://code.google.com/p/yaml-cpp/issues/detail?id=182), and I haven't had a chance to test or merge the fix yet.



来源:https://stackoverflow.com/questions/14608273/defining-custom-input-types-for-the-new-yaml-cpp-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!