У меня есть boost::variant
по множеству конструктивных (и, возможно, даже непередвигаемых/не копируемых и не копируемых/перемещаемых) классов по умолчанию, имеющих существенные разные прототипы конструкторов, отличных от стандартного , как показано ниже:push to list of boost :: variant's
#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;
. Но что мне делать, если конструктор не является конверсионным? То есть имеют более одного параметра. Или что мне делать, если у двух разных типов базиса есть неоднозначные прототипы конструктора? На мой взгляд, это дефект реализации библиотеки boost::variant
в свете новых возможностей стандарта C++ 11, если любой из них может быть применен для решения проблемы.
Я специально спросил о std::list
и boost::variant
в суперпозиции, потому что они оба внутренне реализовать Pimpl идиомы в той или иной форме, насколько я знаю (скажем, boost::variant
в настоящее время разработаны с помощью temporary heap backup approach).
Вам нужен контейнер и 'emplace', чтобы увидеть эту проблему? Предположительно, проблема двусмысленности, например. может возникнуть просто с простой конструкцией «boost :: variant». Что происходит с 'V v (3, std :: string (" 3 "));'? –
'V v (3, std :: string (" 3 "));' приводит к ошибке 'no matching function для вызова to boost :: variant :: variant (int , std :: string) ''' note: шаблон аргумент вычет/замещение не удалось' примечание: кандидат ожидает 1 аргумент, 2 предоставлен' –
Orient
. Ваше предположение верно. Я просто проиллюстрировал пример реального контекста. 'std :: list' не является обязательным. – Orient