#include "MassivePOD.h"
#include "DependantClass.h" // Constructor: `DependantClass(MassivePOD&)`
class ExplicitSolution
{
public:
ExplicitSolution() : m_pod{...}, m_dep{m_pod} { };
private:
MassivePOD m_pod;
DependantClass m_dep;
};
template<typename... T>
class TemplatedSolution
{
public:
template<typename... TupArgs> TemplatedSolution(TupArgs...);
private:
// Can assume in-order construction works
std::tuple<T...> m_tuple;
};
int main()
{
ExplicitSolution a{}; // Easy!
TemplatedSolution<MassivePOD, DependantClass> b{
std::forward_as_tuple(...) // Forwarded to MassivePOD constructor
, std::forward_as_tuple(???) // Forwarded to DependantClass constructor
}; // Hard?
}
Надеюсь, этот пример иллюстрирует мою проблему. Я хотел бы сделать ссылку на ранее построенный член std::tuple
до того, как будет построено целое std::tuple
. Есть ли элегантное решение? Я знаю, что возможно с использованием void *
хакеров, но я бы скорее попросил помощи, прежде чем спуститься по этой темной одинокой дороге.Использовать ссылки на std :: tuple во время строительства?
Идея 1
Я попытался сделать get_ref
функцию, но я получаю ту же проблему, что я не могу получить доступ к функции-члена объекта, который не был создан еще. Впрочем, вот одна из моих попыток.
#include <tuple>
#include <utility>
class Foo // simplified base-case
{
public:
constexpr Foo(int x, char y, int& z) : m_tup{x, y, z*5.0} { };
constexpr int& get_int() { return std::get<0>(m_tup); };
constexpr char& get_char() { return std::get<1>(m_tup); };
constexpr double& get_double() { return std::get<2>(m_tup); };
private:
std::tuple<int, char, double> m_tup;
};
int main()
{
auto super = Foo(5, 'a', ::get_int()); // ???
}
Идея 2
Тогда я подумал, может быть, я мог бы сделать что-то вроде того, что std::function
делает с std::place_holders
, поэтому статический объект, который содержит указатель/ссылку, где каждый элемент std::tuple
было бы. Я думаю, что это стоит попробовать, но я не знаю, как его реализовать на практике ...
Почему вы делаете 'forward_as_tuple'? Использует ли 'ExpensiveToCopyPOD' кортеж в конструкторе? – Claudiu
@Claudiu Я расширяю значения кортежа в конструкторе 'ExpensiveToPOD', и я делаю это, потому что вывод конструктивной арности - действительно сложная проблема сама по себе. –
Обратите внимание, что элементы 'std :: tuple' не гарантируются для создания/инициализации в порядке аргументов шаблона. Фактически, по крайней мере одна популярная реализация делает это «назад». – aschepler