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

Posted

技术标签:

【中文标题】为新的 yaml-cpp API 定义自定义输入类型【英文标题】:Defining custom input types for the new yaml-cpp API 【发布时间】:2013-01-30 16:00:32 【问题描述】:

我正在尝试使用新型 YamlCpp API 定义一些自定义输入类型。我有两个问题。首先让我说,我们目前使用的是 0.3 style-api,一切都很好。新 API 的代码外观提高了大约 10 倍,因此我们希望使用它。

    为什么我当前的方法会使编译器失效? yaml-cpp 是否足够智能以处理嵌套模板。例如,如果我的解析器知道如何 enc/dec std::vectors,然后我为 MyAwesomeType 单独定义一个自定义处理程序——我可以要求它 enc/dec a std::vector<MyAwesomeType> 并且它会弄清楚吗?李>

我的代码首先复制并粘贴网站上的示例 (here),然后对其进行修改。我当前的实现尝试处理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"] ) 

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

【问题讨论】:

【参考方案1】:

是的,yaml-cpp 应该能够处理嵌套模板(因此您不需要为 std::vector&lt;std::pair&lt;qint16, qint16&gt;&gt; 定义转换 - 而且,这表明 yaml-cpp 通常应该为 std::pair&lt;T, U&gt; 定义转换(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),我还没有机会测试或合并修复。

【讨论】:

好的,谢谢。我会注意并关注这两个错误。不,ALL_BUILD 无法编译其中一个部分。我会将构建日志发布到问题跟踪器 如果您已经有修复程序,请告诉我如何尽快帮助测试。

以上是关于为新的 yaml-cpp API 定义自定义输入类型的主要内容,如果未能解决你的问题,请参考以下文章

在 python C API 中返回新的自定义类对象的列表

在visual studio 2010中为新的QOBJECT文件生成MOC

Streamlabs 自定义 CSS 事件列表 - 为新条目添加延迟

如何将自定义 osgi 包添加为新依赖项?

java中自定义异常类

使用 yaml-cpp 0.5 DLL 时的链接器错误