Он не работает главным образом потому, что псевдоним result
в Id
имеет значение private (доступность по умолчанию для классов) и поэтому недоступен из частного конструктора SeveralPrinters
, что приводит кошибка замещения (typename Id<Args1>::result
) без другого жизнеспособного конструктора-кандидата для вызова.В вашем коде также было несколько опечаток.
template <typename T>
struct Id
{
using result = T;
};
template <typename Printer1, typename Printer2>
class SeveralPrinters : public Printer1, public Printer2
{
template <typename... Args1, typename... Args2>
SeveralPrinters(dummy, helper<Args1...>, helper<Args2...>
, typename Id<Args1>::result... args1
, typename Id<Args2>::result... args2)
: Printer1(std::forward<Args1>(args1)...)
, Printer2(std::forward<Args2>(args2)...)
{}
public:
template <typename... Args>
SeveralPrinters(Args&&... args)
: SeveralPrinters(dummy{}
, typename Printer1::ArgsCtor{}
, typename Printer2::ArgsCtor{}
, std::forward<Args>(args)...)
{}
};
DEMO
Для идеальной пересылки аргументовдля базовых классов вы должны вместо этого объявить количество параметров (ArgsCount
) и использовать следующую реализацию:
template <typename Printer1, typename Printer2>
class SeveralPrinters : public Printer1, public Printer2
{
template <std::size_t... Is
, std::size_t... Js
, typename... Args>
SeveralPrinters(std::index_sequence<Is...>
, std::index_sequence<Js...>
, std::tuple<Args...>&& t)
: Printer1(std::get<Is>(std::move(t))...)
, Printer2(std::get<sizeof...(Is) + Js>(std::move(t))...)
{}
public:
SeveralPrinters() = default;
SeveralPrinters(const SeveralPrinters&) = default;
SeveralPrinters(SeveralPrinters& rhs)
: SeveralPrinters(static_cast<const SeveralPrinters&>(rhs))
{}
template <typename... Args>
SeveralPrinters(Args&&... args)
: SeveralPrinters(std::make_index_sequence<Printer1::ArgsCount>{}
, std::make_index_sequence<Printer2::ArgsCount>{}
, std::forward_as_tuple(std::forward<Args>(args)...))
{}
};
struct BasicPrinter1
{
BasicPrinter1(int) {}
static constexpr ArgsCount = 1;
};
struct BasicPrinter2
{
BasicPrinter2(int*, char&) {}
static constexpr ArgsCount = 2;
};
DEMO 2
Также обратите внимание на то, как я защищаю конструктор копирования от того, чтобы он был омрачен конструктором пересылочных ссылок.