【问题标题】:Boost.Bind return typeBoost.Bind 返回类型
【发布时间】:2014-01-15 13:46:57
【问题描述】:

我正在尝试用 Boost.Assign 填充 boost::property_tree::ptree。所以,我得到了以下工作正常:

namespace bpt = boost::property_tree;
bpt::ptree pt;
boost::assign::make_list_inserter
    (boost::bind(&bpt::ptree::put<std::string>, pt, _1, _2))
        ("one.two.three", "four")
        ("one.two.five", "six");

但是,当我试图让这段代码看起来更好看时,它无法编译:

typedef bpt::ptree& (bpt::ptree::*PutType)
    (const bpt::path_of<std::string>::type&, const std::string &);

PutType Put = &bpt::ptree::put<std::string>;

inline boost::assign::list_inserter<PutType> put(bpt::ptree &pt) {
  PutType putFunction = boost::bind(Put, pt, _1, _2); // !!! compile error
  return boost::assign::make_list_inserter(putFunction);
}

//and use it like:
put(pt)
    ("one.two.three", "four")
    ("one.two.five", "six");

错误信息是

SomeFile.cpp: 在函数'boost::assign::list_inserter<:property_tree::ptree boost::property_tree::string_path string boost::property_tree::id_translator> >&, const std::string&), boost::assign_detail::forward_n_arguments> put(boost::property_tree::ptree&)':

SomeFile.cpp:42: 错误:无法转换 'boost::_bi::bind_t<:property_tree::ptree boost::_mfi::mf2 boost::property_tree ::ptree const boost::property_tree::string_path boost::property_tree::id_translator> >&, const std::string&>, boost::_bi::list3, boost::arg, boost::arg > >' to 'boost::property_tree::ptree& (boost::property_tree:: ptree::*)(const boost::property_tree::string_path<:string boost::property_tree::id_translator> >&, const std::string&)' 在初始化中

使代码正常工作的最佳方法是什么?

【问题讨论】:

    标签: c++ boost boost-bind c++03 boost-propertytree


    【解决方案1】:

    代码中有几个错误:

    1. boost::bind() 按值存储绑定参数,以便boost::bind(&amp;bpt::ptree::put&lt;std::string&gt;, pt, _1, _2) 复制pt 并填充该副本。改为传递指针:boost::bind(&amp;bpt::ptree::put&lt;std::string&gt;, &amp;pt, _1, _2) 或使用 boost::ref(pt)
    2. boost::bind 返回的对象无法转换为指针类型,这就是PutType putFunction = boost::bind(Put, pt, _1, _2); 无法编译的原因。

    在没有 auto 关键字的 C++03 中,您无法轻松捕获 boost::bindboost::list_inserter 的类型。您可以将两者的结果包装到 boost::function&lt;&gt; 中,但在我看来,这将过于严厉。

    但是你可以在 C++03 中使用 plain 实现所需的语法:

    namespace bpt = boost::property_tree;
    
    struct PtreeInserter
    {
        bpt::ptree* pt;
    
        PtreeInserter(bpt::ptree& pt) : pt(&pt) {}
    
        template<class A1, class A2>
        PtreeInserter const& operator()(A1 a1, A2 a2) const {
            pt->put(a1, a2);
            return *this;
        }
    };
    
    int main() {
        bpt::ptree pt;
        typedef PtreeInserter put;
        put(pt)
            ("one.two.three", "four")
            ("one.two.five", "six");
    }
    

    【讨论】:

    • 谢谢 (+1)。你知道,我怎样才能重写代码来让它工作?
    • 再次感谢您。为什么boost::function 是强硬的?是否存在一些性能损失?
    • @Loom boost::function 在构造和复制时涉及内存分配;和调用时的指针间接。它针对一些简单的情况进行了优化以避免内存分配,但这些情况并非如此。
    猜你喜欢
    • 1970-01-01
    • 2021-03-11
    • 2014-12-09
    • 2021-04-15
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多