boost-1.55 boost :: property_tree :: ptree用C ++ 11编译吗? [英] does boost-1.55 boost::property_tree::ptree compile with c++11?

查看:236
本文介绍了boost-1.55 boost :: property_tree :: ptree用C ++ 11编译吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编译以下源代码

I'm trying to compile the following source code

#include <boost/property_tree/ptree.hpp>

int main() {
    boost::property_tree::ptree b;
    b.push_back(std::make_pair("a", "b"));

    return 9;
}

使用以下编译器和说明:

using the following compiler and instructions:

$ g++ ./source.cpp --std=c++11
$ g++ --version
g++ (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ # boost version is 1.55

我遇到以下错误

./source.cpp: In function ‘int main()’:
./source.cpp:5:41: error: no matching function for call to ‘boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> >::push_back(std::pair<const char*, const char*>)’
     b.push_back(std::make_pair("a", "b"));
                                     ^
In file included from /opt/boost/boost_1_55_0/boost/property_tree/ptree.hpp:516:0,
                 from ./source.cpp:1:
/opt/boost/boost_1_55_0/boost/property_tree/detail/ptree_implementation.hpp:362:9: note: candidate: boost::property_tree::basic_ptree<Key, Data, KeyCompare>::iterator boost::property_tree::basic_ptree<Key, Data, KeyCompare>::push_back(const value_type&) [with Key = std::basic_string<char>; Data = std::basic_string<char>; KeyCompare = std::less<std::basic_string<char> >; boost::property_tree::basic_ptree<Key, Data, KeyCompare>::value_type = std::pair<const std::basic_string<char>, boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> > >]
         basic_ptree<K, D, C>::push_back(const value_type &value)
         ^
/opt/boost/boost_1_55_0/boost/property_tree/detail/ptree_implementation.hpp:362:9: note:   no known conversion for argument 1 from ‘std::pair<const char*, const char*>’ to ‘const value_type& {aka const std::pair<const std::basic_string<char>, boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char> > >&}’

注意:如果我不使用--std = c ++ 11进行编译,该错误就会消失

NOTE: if I'm compiling this without --std=c++11 the error disappears

问题:如何使用c ++ 11标准或更高版本进行编译?我发现 https://svn.boost.org/trac10/ticket/6785,但在boost-1.55中它已得到修复.预先谢谢你!

QUESTION: how may I compile it using c++11 standard or higher? I've found https://svn.boost.org/trac10/ticket/6785 , but in boost-1.55 it has been already fixed. thank you in advance!

推荐答案

是的.真正的变化是std::make_pair.

C ++ 11更改了std::pair转换规则以及make_pair便利功能,该功能具有移动意识.

C++11 changed std::pair conversion rules, as well as the make_pair convenience function, which was made move-aware.

属性树允许这样的构造:

Property Tree allows construction like this:

ptree pt("data");

构造仅包含值数据而没有子节点的树.但是,该对second成员的间接转换不适用于c ++ 11模式:

to construct a tree with only value data and no child nodes. However, the indirect conversion for the second member of the pair doesn't apply in c++11 mode:

std::pair<std::string, ptree> v = std::make_pair("a", "b");

该行本可以在c ++ 03中进行编译,但不再在c ++ 11中进行编译

This line would have compiled in c++03, but no longer compiles in c++11

要弄清楚它可能是libstdc ++还是编译器错误,我将其隔离到以下最小示例中:

To find out whether it might be a libstdc++ or compiler bug, I isolated it into this minimal sample:

#include <utility>
#include <string>

struct X {
    X(std::string){}
};

int main() {
    std::pair<std::string, X> v = std::make_pair("a", "b");
}

注意的一个微妙之处是,构造函数不是explicit并不重要,就像ptree(data_type const&)构造函数一样.所需的额外的隐式转换char const(&)[] -> std::string足以导致c ++ 11拒绝调用.

Note the subtle point that it doesn't matter that the constructor isn't explicit like with the ptree(data_type const&) constructor. The additional implicit conversion char const(&)[] -> std::string required is enough to cause c++11 to reject the call.

在c ++ 03中编译,但只需检查一下, c同意,即使使用

Just to check, clang agrees even when using libc++ instead of libstdc++.

我敢打赌,这是设计使然,可能是使std::make_pair更精确并了解移动语义的结果.

At I bet this is by design and probably a result of making std::make_pair more precise and aware of move-semantics.

如何修复

解决方法是多种多样的.明确转换:

How To Fix

The workarounds are manifold. Convert explicitly:

b.push_back(std::make_pair("a", ptree("b")));

明确显示类型总是有帮助的:

Making types explicit always helps:

b.push_back(ptree::value_type {"a", "b"});

统一初始化消除了一些麻烦:

Uniform initialization removes some cruft:

b.push_back({"a", ptree{"b"}});

出于完整性考虑,非显式构造函数更加灵活:

For completeness, non-explicit constructors are more flexible:

b.push_back({"a", {}});


或者您可以完全避免使用pair<>(value_type)界面:


Or you can avoid the pair<> (value_type) interface altogether:

b.add_child("a", ptree{"b"});
b.add_child("a", {}).put_value("b");

但是这里真正的关键是值节点不能有孩子.为什么不输入值?

But the real key here is that value nodes cannot have children. Why not just put the value?

b.add("a", "b");

这是我的建议.我觉得std::pair<>是一个实现细节,仅用于与其他通用代码互操作.这会损害可读性.

This is my RECOMMENDATION. I feel std::pair<> is an implementation detail only useful to interoperate with other generic code. It hurts readability.

实时演示

所有变通办法愉快地生活在一起 在Coliru上生活

打印

<?xml version="1.0" encoding="utf-8"?>
<a>b</a>
<a>b</a>
<a>b</a>
<a/>
<a>b</a>
<a>b</a>
<a>b</a>

这篇关于boost-1.55 boost :: property_tree :: ptree用C ++ 11编译吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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