为新的yaml-cpp API定义自定义输入类型 [英] Defining custom input types for the new yaml-cpp API

查看:168
本文介绍了为新的yaml-cpp API定义自定义输入类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  1. 为什么我当前的方法会使编译器崩溃?
  2. yaml-cpp是否足够智能以处理嵌套模板.例如,如果我的解析器知道如何对std :: vectors进行编码/解码,然后我分别为MyAwesomeType定义了自定义处理程序-我可以要求它对std::vector<MyAwesomeType>进行编码/解码并找出答案吗?

我的代码首先将示例复制并粘贴到网站上(此处),然后对其进行修改.我当前的实现尝试处理std::vector<std::pair<qint16,qint16>>的转换-无法编译. (仅供参考-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"] ) 

行 我使用默认分支的修订版573从最新的源代码重新编译,所有这些示例均来自该代码.

解决方案

是的,yaml-cpp应该能够处理嵌套模板(因此您无需为std::vector<std::pair<qint16, qint16>>定义转换-这表明yaml-cpp通常应为std::pair<T, U>定义一个转换( http://code.google.com/p/yaml-cpp/issues/detail?id=188 )).

我不确定为什么编译器不接受您的代码(它看起来正确,并且对我来说在Linux上可以正常编译).

测试完全可以编译吗?显然,0.5.0不能在Visual Studio上开箱即用(请参见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.

解决方案

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.

这篇关于为新的yaml-cpp API定义自定义输入类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆