我正在尝试使用emplace()
来构建map<K,V>
条目(使用Boost)。密钥对象构造函数arg通过模板魔法正确转发,但V object
构造函数arg变为const,因此它不起作用。
#include <boost/container/map.hpp>
class A {
public:
/**/ A( int n ) { }
friend bool operator<( const A &a1, const A &a2 ) { return false; }
} ;
class B {
public:
/**/ B( const char *str ) { }
} ;
class C {
public:
/**/ C( B &b ) { }
} ;
int
main( int, char ** )
{
boost::container::map<A,B> m1;
boost::container::map<A,C> m2;
B b( "Foo" );
C c( b ); // <--- this works OK.
m1.emplace( 1, "Hello" );
m2.emplace( 2, b ); // <----- this fails!
}
错误是:
Error: /usr/local/include/boost/container/detail/pair.hpp:128:38: error: no matching function for call to C::C(const B&), second(::boost::forward<V>(v))
关于emplace参数转发的内容在最后一行将b
转换为const b
。我知道必须有一个boost::bla_bla_bla
我可以申请使它运作,但我找不到它。
有人可以帮忙吗?
答案 0 :(得分:1)
请注意,如果使用-std=c++11
(或更高版本)进行编译,则可以使用此功能。为什么会出现这种情况需要花一点时间 - 我使用的是较早版本的boost(1.56),但我怀疑这两个版本之间的变化很大。
使用emplace
通常需要完美转发。这意味着所有参数都通过std::forward<Args>(args)...
转发。在下面,这依赖于引用折叠和移动语义 - 这是所有C ++ 11领域,并且在C ++ 03中没有模拟。
如果我们深入研究pair
的增强代码(它实际上产生了错误),那么这就是它试图调用的构造函数:
template<class U, class V>
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
: first(::boost::forward<U>(u))
, second(::boost::forward<V>(v))
{}
不幸的是,BOOST_FWD_REF
(位于move/core.hpp
中)是以下之一:
#define BOOST_FWD_REF(TYPE)\
const TYPE & \
//
#define BOOST_FWD_REF(TYPE)\
const TYPE & \
//
当您的编译器无法识别右值引用时,它将变为const TYPE&
。
对此on the boost archives list进行了一些讨论。
最简单的解决方案是使用std=c++11
编译。