boost-1.55 boost :: property_tree :: ptree用C ++ 11编译吗? [英] does boost-1.55 boost::property_tree::ptree compile with 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 theptree(data_type const&)
constructor. The additional implicit conversionchar 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屋!