推送到boost::variant';s

推送到boost::variant';s,boost,c++11,boost-variant,Boost,C++11,Boost Variant,我的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)

我的
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;
}
#包括
#包括
#包括
结构A{A(int){;}};
结构B{B(std::string){;};
结构C{C(int,std::string){;};
使用V=boost::variant;
使用L=std::list;
int main()
{
L;
l、 向后推(A(1));//一个额外的复制/移动操作
l、 向后推(B(“2”);//一个额外的复制/移动操作
l、 向后推(C(3,3”);//一个额外的复制/移动操作
l、 后置(4);
l、 向后放置(标准:字符串(“5”);
//l.emplace_back(3,std::string(“3”);//此处出错
返回0;
}
我希望,
std::list::emplace_back
允许我(在单个操作中)构造和插入新对象(所有
A
B
C
类型),即使它们有
T&operator=(T const&)=delete/
T&运算符=(T&&)=删除
T(T常数&)=删除/
T(T&&)=删除。但如果构造函数是非转换的,我应该怎么做呢?即,具有多个参数。或者,如果两个不同变体的底层类型具有不明确的构造函数原型,我应该怎么做?根据C++11标准的新特性,我认为这是
boost::variant
库实现的缺陷,如果有任何问题,可以应用它来解决


我特别询问了叠加的
std::list
boost::variant
,因为据我所知,它们都以某种形式在内部实现了pimpl习惯用法(比如,
boost::variant
,目前通过设计)。

emplace
只能调用所讨论类型的构造函数。和
boost::variant
的构造函数只接受可以明确转换为variant类型之一的单个对象

variant
不会将参数任意转发到它的一个有界类型。它只需要一个值。它将尝试转换为某个有界类型的单个值


因此,您必须构造一个对象,然后将其复制到
变量中

假设您可以修改“C”类,您可以为它提供一个附加的构造函数,该构造函数接受一个元组参数。

是否需要一个容器和
模板
来查看此问题?例如,简单构造一个
boost::variant
,可能会出现歧义问题。V(3,std::string(“3”))会发生什么
V(3,std::string(“3”)导致一个错误
调用'boost::variant::variant(int,std::string)'时没有匹配函数
注意:模板参数推断/替换失败
注意:如果您的假设是正确的,候选人需要1个参数,2个参数。我只是用一个真实背景的例子来说明<代码>标准::列表
不是强制性的。
boost::variant
只是没有像
templateboost::vector::vector(Args&&…Args)
将参数分派给相应底层类型的构造函数
p=new T(Args。但是如果我的类型是不可复制/可移动和不可复制/可移动的,我该怎么办?我认为,
std::is_constructible
和一些元编程魔术可以帮助
boost::variant
设计器实现这种构造函数。@Dukales:“但是,如果我的类型是不可复制/可移动和不可复制/移动构造的,我该怎么办?”那么你不能在变体中使用它。至于创建此类构造函数的能力,这可能是可能的,但对于
boost::variant
,它现在肯定不存在。