次の疑似コードを検討してください。
template<class... T>
struct worker : unique<T...>::type...{};
struct x{};
struct y{};
struct z{};
s のunique
中で一意の型のみで構成されるパラメーター パックを生成するようにテンプレートを作成することは可能ですか?T
worker<x,y,x,z>
x
y
z
T
次の疑似コードを検討してください。
template<class... T>
struct worker : unique<T...>::type...{};
struct x{};
struct y{};
struct z{};
s のunique
中で一意の型のみで構成されるパラメーター パックを生成するようにテンプレートを作成することは可能ですか?T
worker<x,y,x,z>
x
y
z
T
AFAIK: いいえ。
問題は、それがディレクティブtype
の結果であり、パックをエイリアスできないことです。これは実際には面倒であり、ほとんどの場合、パックの計算では、それらを渡すためだけにラッパー タイプ ( など) を導入する必要があります。typedef
typedef
template <typename...> struct pack {};
パラメータパックは簡単に保存できないので、やりたいことができないと思います。ただし、一連のベースから継承するにはこの機能が必要なように思われるため、テンプレート メタプログラミングを使用して、セット内のすべてのベースから線形に継承するベース タイプを作成できます。その前に、パラメータ パックから重複を簡単にフィルタリングできます。
Boost.MPLを使用したこのアプローチの実装を次に示します。
#include <boost/mpl/fold.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/vector.hpp>
namespace mpl = boost::mpl;
template < typename ...Args >
struct inherit_uniquely
{
// filter out duplicates
typedef typename
mpl::fold<
mpl::vector< Args... >,
mpl::set0<>,
mpl::insert< mpl::_1, mpl::_2 >
>::type unique_bases;
// create base type
typedef typename
mpl::inherit_linearly<
unique_bases,
mpl::inherit< mpl::_1, mpl::_2 >
>::type type;
};
template < typename ...Bases >
struct Derived : inherit_uniquely< Bases... >::type
{};
struct X { int x;};
struct Y { int y;};
struct Z { int z;};
int main()
{
Derived< X, Y, Z > d;
d.x = 1;
d.y = 2;
d.z = 3;
X& d_as_x = d;
Y& d_as_y = d;
Z& d_as_z = d;
}