为新的yaml-cpp API定义自定义输入类型

时间:2013-01-30 16:00:32

标签: yaml-cpp

我正在尝试使用新式的YamlCpp API定义一些自定义输入类型。我有两个问题。首先我要说的是,我们目前正在使用0.3 style-api,一切都很棒。新API的代码外观大约好了10倍,所以我们想要转向它。

  1. 为什么我目前的方法会使编译器发生错误?
  2. yaml-cpp是否足够智能来处理嵌套模板。例如,如果我的解析器知道如何enc / dec std :: vectors,然后我分别为MyAwesomeType定义一个自定义处理程序 - 我可以要求它对std::vector<MyAwesomeType>进行加/减,它会解决吗?
  3. 我的代码首先复制并粘贴网站上的示例(here)然后修改它。我当前的实现尝试处理std::vector<std::pair<qint16,qint16>>的转换 - 这不会编译。 (fyi - qint16只是__int16的跨平台typedef)

    #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;
          }
       };
    }
    

    最后,我想用它来调用

    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>>>();
        }
    }
    

    ...基于输入yaml,看起来像这样......

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

    由此产生的编译器错误大约是300行,所以我不会在这里发布。 平台:Visual Studio 2010 SP1 x64

    感谢您的帮助。

    修改 这是我得到的许多错误中的第一个错误,即使用新样式解析Node键并不高兴...我添加了这个因为导致这个错误的原因可能与另一个相关错误。
    代码

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

    原因

    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>          ]
    

    请注意,上面错误中提到的第75行是

    if( doc["numPixels"] ) 
    

    线 我使用默认分支的Rev 573从源代码重新编译,所有这些示例都来自该代码。

1 个答案:

答案 0 :(得分:1)

是的,yaml-cpp应该能够处理嵌套模板(因此您不需要为std::vector<std::pair<qint16, qint16>>定义转换 - 并且这表明yaml-cpp应该为{{1}定义转换一般来说(http://code.google.com/p/yaml-cpp/issues/detail?id=188))。

而且我不确定为什么编译器不接受你的代码(它看起来是正确的,并且在我的Linux上编译得很好)。

测试是否完全编译?显然,0.5.0在Visual Studio上没有开箱即用(参见http://code.google.com/p/yaml-cpp/issues/detail?id=182),我还没有机会测试或合并修复程序。