如果所有可用于x、y 和z 的类型全部都派生自一个公共基类,即基指针解决方案,std::unique_ptr (+ 1 for Lyubomir Stankov),是(恕我直言)一个很好的解决方案。
但是你问“是否可以让 bar 成为具有多个模板参数的模板类”。
是的:这是可能的。不是很优雅(恕我直言),但可能。
为了好玩,我提出了以下解决方案,但我认为,在更一般的情况下(请注意,在我的示例中,A 和 B 是不相关的类,而不是从 foo 派生而来)有用(希望如此)
#include <tuple>
#include <string>
#include <utility>
class A
{
private:
double d;
std::string s;
public:
A (double d0, std::string s0) : d { d0 }, s { s0 } { }
};
class B
{
private:
long l;
public:
B (long l0) : l { l0 } { }
};
template <typename Tx, typename Ty, typename Tz>
class bar
{
private:
template <typename ... Ts>
using tpl = std::tuple<Ts...>;
template <std::size_t ... Is>
using is = std::index_sequence<Is...> const;
template <std::size_t N>
using mis = std::make_index_sequence<N>;
Tx x;
Ty y;
Tz z;
template <typename ... Tsx, std::size_t ... Isx,
typename ... Tsy, std::size_t ... Isy,
typename ... Tsz, std::size_t ... Isz>
bar (tpl<Tsx...> const & tx0, is<Isx...> const &,
tpl<Tsy...> const & ty0, is<Isy...> const &,
tpl<Tsz...> const & tz0, is<Isz...> const &)
: x { std::get<Isx>(tx0) ... },
y { std::get<Isy>(ty0) ... },
z { std::get<Isz>(tz0) ... }
{ }
public:
template <typename ... Tsx, typename ... Tsy, typename ... Tsz>
bar (tpl<Tsx...> const & tx0,
tpl<Tsy...> const & ty0,
tpl<Tsz...> const & tz0)
: bar(tx0, mis<sizeof...(Tsx)> {},
ty0, mis<sizeof...(Tsy)> {},
tz0, mis<sizeof...(Tsz)> {})
{ }
};
int main()
{
bar<A, B, A> aba{ std::make_tuple(2.3, "str1"),
std::make_tuple(4),
std::make_tuple(5.4, "str2") };
bar<B, A, B> bab{ std::make_tuple(3),
std::make_tuple(3.2, "str3"),
std::make_tuple(5) };
}
不幸的是,这个示例使用了 C++14 特性的 std::make_index_sequence 和 std::index_sequence。
如果你想在 C++11 中实现 foo,你可以实现下面的结构体 struct indexSeq 和 struct indexSeqHelper,来替换 std::index_sequence 和 std::make_index_sequence
template <std::size_t ...>
struct indexSeq
{ };
template <std::size_t N, std::size_t ... Next>
struct indexSeqHelper
{ using type = typename indexSeqHelper<N-1U, N-1U, Next ... >::type; };
template <std::size_t ... Next >
struct indexSeqHelper<0U, Next ... >
{ using type = indexSeq<Next ... >; };
并定义is和mis如下
template <std::size_t ... Is>
using is = indexSeq<Is...>;
template <std::size_t N>
using mis = typename indexSeqHelper<N>::type;