У меня есть этот тип:
struct immobile {
// other stuff omitted
immobile(immobile&) = delete;
immobile(immobile&&) = delete;
};
immobile mk_immobile();
// e.g. this compiles
// mk_immobile() is a prvalue and i is its result object
immobile i(mk_immobile());
У меня также есть этот шаблон класса:
template<typename T>
struct container {
std::variant<T, other_stuff> var;
template<typename... Args>
container(Args&&... args)
: var(std::in_place_index<0>, std::forward<Args>(args)...) {}
};
Я хочу построить container
вокруг объекта, созданного mk_immobile()
,с объектом immobile
, используемым для инициализации одного из вариантов var
.
container<immobile> c(mk_immobile());
Однако это не работает.Например, конструктор std::variant
хочет std::is_constructible_v<immobile, immobile>
, что не выполняется.Хуже того, даже эта упрощенная версия дает сбой:
template<typename T>
struct demonstration {
T t;
template<typename... Args>
demonstration(Args&&... args) : t(std::forward<Args>(args)...) {}
};
demonstration<immobile> d(mk_immobile());
Что, по-видимому, означает, что std::forward
, на самом деле, не идеально вперед - prvalues не передаются как prvalues.(Это имеет смысл для меня; я не думаю, что это было бы возможно.) Я могу заставить demonstration
работать, изменив его на следующее:
template<typename T>
struct demonstration {
T t;
template<typename F>
demonstration(F&& f) : t(std::forward<F>(f)()) {}
};
demonstration<immobile> d([] { return mk_immobile(); });
Но я не вижу способа изменитьcontainer
аналогичным образом.Как мне изменить container
, чтобы он мог создать std::variant
(или другой теговый союз) из значения?Я могу изменить container
, но не могу изменить immobile
.