3

次のクラスを検討してください。

template<class T, int...> struct MyClass1 {};
template<class T, unsigned int...> struct MyClass2 {};
template<class T, long long int...> struct MyClass3 {};
template<class T, unsigned long long int...> struct MyClass4 {};

これらのクラスを変更することはできません。

可変長リストの型を返すヘルパークラスや関数などを書くことは可能ですか?

something<MyClass1>::type (-> int)
something<MyClass2>::type (-> unsigned int)
something<MyClass3>::type (-> long long int)
something<MyClass4>::type (-> unsigned long long int)

size_t可変長リストが空の場合は?

4

1 に答える 1

0

I couldn't come up with a way to define one generic metafunction that does it, but here is a possible workaround:

#include <iostream>
#include <type_traits>

using namespace std;

// PRIMARY TEMPLATE

template<typename T>
class something
{
};

// SPECIALIZATIONS FOR int

template<typename T, int... U, template<typename, int...> class L>
class something<L<T, U...>>
{
public:
    typedef int type;
};

template<typename T, template<typename, int...> class L>
class something<L<T>>
{
public:
    typedef size_t type;
};

// SPECIALIZATIONS FOR unsigned int

template<typename T, unsigned int... U, template<typename, unsigned int...> class L>
class something<L<T, U...>>
{
public:
    typedef unsigned int type;
};

template<typename T, template<typename, unsigned int...> class L>
class something<L<T>>
{
public:
    typedef size_t type;
};

/* ... OTHER SPECIALIZATIONS ... */

struct A {};
struct B {};

int main()
{
    static_assert(is_same<something<MyClass1<A, 1, 2>>::type, int>::value, "Error!");
    static_assert(is_same<something<MyClass1<A>>::type, size_t>::value, "Error!");
    static_assert(is_same<something<MyClass2<B, 1U, 2U, 3U>>::type, unsigned int>::value, "Error!");
    static_assert(is_same<something<MyClass2<B>>::type, size_t>::value, "Error!");
    return 0;
}

I tried to write only single specialization that would cover all cases, like this:

template<typename U, typename T, U... V, template<typename, U...> class L>
class something<L<T, V...>>
{
public:
    typedef U type;
};

But Clang 3.2 complains that the type of U cannot be deduced, so this specialization of get_type will never be used. So if you follow this approach you will have to explicitly define each specialization. This may or may not be acceptable depending on your use cases. Hope it helps.

于 2012-12-27T18:02:03.313 に答える