[英]C++, pass two parameter packs to constructor
我有以下问题。 我有一个类( mixin ),它有两个模板库。
template <typename T>
class 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)..., std::forward<Args2>(args2)...)
{}
public:
template <typename... Args, typename =
std::enable_if_t<!contains<dummy, Args...>::result>>
SeveralPrinters(Args&&... args)
: SeveralPrinters(dummy(), typename Printer1::ArgsCtor(),
typename Printer2::ArgsCtor(), std::forward<Args>(args)...)
{
}
};
所有类的名称都是虚构的。 所以,想象一下它的第一个基数接受int
作为构造函数参数,第二个基数接受double
。 我想要做的是能够像SeveralPrinters(1, 2.)
一样调用SeveralPrinters
构造函数。 这里的问题是Args1
和Args2
不是从helper
结构推导出来的,而是从辅助结构之后传递的 args 推导出来的。 如您所见,我尝试将模板参数包装到Id
结构中,但这没有帮助。 我知道,它被称为 smth like Non-deduced contexts ,但我无法让它工作。 任何人都可以提供帮助(如果可能的话),并且可能会就此主题进行更多解释(为什么它现在不起作用)。 基类示例:
class BasicPrinter1
{
public:
BasicPrinter1(int)
{}
void f()
{
}
using ArgsCtor = helper<int>;
};
class BasicPrinter2
{
public:
BasicPrinter2(int*)
{}
void g()
{
}
using ArgsCtor = helper<int*>;
};
它不起作用主要是因为Id
的别名result
是私有的(类的默认可访问性),因此无法从SeveralPrinters
的私有构造函数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)...)
{}
};
为了完美地将参数转发给基类,您应该声明参数的数量( 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;
};
还要注意我是如何保护复制构造函数不被转发引用构造函数所掩盖的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.