我有boost::variant
一组非默认的可构造(甚至可能是不可移动/不可复制和非复制/移动可构造)类,其中包含必要的非默认构造函数原型,如下所示:
#include <boost/variant.hpp>
#include <string>
#include <list>
struct A { A(int) { ; } };
struct B { B(std::string) { ; } };
struct C { C(int, std::string) { ; } };
using V = boost::variant< A const, B const, C const >;
using L = std::list< V >;
int main()
{
L l;
l.push_back(A(1)); // an extra copy/move operation
l.push_back(B("2")); // an extra copy/move operation
l.push_back(C(3, "3")); // an extra copy/move operation
l.emplace_back(4);
l.emplace_back(std::string("5"));
// l.emplace_back(3, std::string("3")); // error here
return 0;
}
我希望,std::list::emplace_back
允许我构建 - 并插入(在单个操作中)新对象(所有A
,B
,C
类型)进入列表,即使他们有T & operator = (T const &) = delete;
/ T & operator = (T &&) = delete;
和T(T const &) = delete;
/ T(T &&) = delete;
。但是,如果构造函数是非转换构造函数,我该怎么办?即拥有更多,而不是一个参数。或者,如果两个不同变体的基础类型具有不明确的构造函数原型,我应该怎么做?在我看来,这是根据C ++ 11标准的新功能实现boost::variant
库的缺陷,如果有的话可以应用来解决问题。
我特别询问了std::list
和boost::variant
的叠加问题,因为据我所知,它们在内部实现了某种形式的 pimpl 习惯用法(例如,{ {1}}目前通过temporary heap backup approach)设计。
答案 0 :(得分:1)
emplace
只能调用相关类型的构造函数。并且boost::variant
的构造函数只接受单个对象,这些对象可以明确地转换为变体类型之一。
variant
不会将参数任意转发到其有界类型之一。它只需要一个值。一个单值,它将尝试转换为其中一个有界类型。
所以你将不得不构建一个对象,然后将其复制到variant
。
答案 1 :(得分:1)
假设你可以修改你的“C”类,你可以给它一个额外的构造函数,它接受一个元组参数。