Nice programing

템플릿 매개 변수 팩을 확장하지 않고 "저장"할 수 있습니까?

nicepro 2020. 10. 27. 23:28
반응형

템플릿 매개 변수 팩을 확장하지 않고 "저장"할 수 있습니까?


이 문제를 발견했을 때 C ++ 0x 가변 템플릿을 실험하고있었습니다.

template < typename ...Args >
struct identities
{
    typedef Args type; //compile error: "parameter packs not expanded with '...'
};

//The following code just shows an example of potential use, but has no relation
//with what I am actually trying to achieve.
template < typename T >
struct convert_in_tuple
{
    typedef std::tuple< typename T::type... > type;
};

typedef convert_in_tuple< identities< int, float > >::type int_float_tuple;

GCC 4.5.0에서 템플릿 매개 변수 팩을 typedef하려고하면 오류가 발생합니다.

기본적으로 매개 변수 팩을 압축을 풀지 않고 typedef에 "저장"하고 싶습니다. 가능합니까? 그렇지 않다면 이것이 허용되지 않는 이유가 있습니까?


Ben보다 약간 더 일반적인 또 다른 접근 방식은 다음과 같습니다.

#include <tuple>

template <typename... Args>
struct variadic_typedef
{
    // this single type represents a collection of types,
    // as the template arguments it took to define it
};

template <typename... Args>
struct convert_in_tuple
{
    // base case, nothing special,
    // just use the arguments directly
    // however they need to be used
    typedef std::tuple<Args...> type;
};

template <typename... Args>
struct convert_in_tuple<variadic_typedef<Args...>>
{
    // expand the variadic_typedef back into
    // its arguments, via specialization
    // (doesn't rely on functionality to be provided
    // by the variadic_typedef struct itself, generic)
    typedef typename convert_in_tuple<Args...>::type type;
};

typedef variadic_typedef<int, float> myTypes;
typedef convert_in_tuple<myTypes>::type int_float_tuple;

int main()
{}

나는 그것이 허용되지 않는 이유는 그것이 지저분해질 것이고 그것을 해결할 수 있다고 생각합니다. 종속성 반전을 사용하고 매개 변수 팩을 다른 템플릿에 적용 할 수있는 팩토리 템플릿에 매개 변수 팩을 저장하는 구조체를 만들어야합니다.

라인을 따라 뭔가 :

template < typename ...Args >
struct identities
{
    template < template<typename ...> class T >
    struct apply
    {
        typedef T<Args...> type;
    };
};

template < template<template<typename ...> class> class T >
struct convert_in_tuple
{
    typedef typename T<std::tuple>::type type;
};

typedef convert_in_tuple< identities< int, float >::apply >::type int_float_tuple;

I've found Ben Voigt's idea very useful in my own endeavors. I've modified it slightly to make it general to not just tuples. To the readers here it might be an obvious modification, but it may be worth showing:

template <template <class ... Args> class T, class ... Args>
struct TypeWithList
{
  typedef T<Args...> type;
};

template <template <class ... Args> class T, class ... Args>
struct TypeWithList<T, VariadicTypedef<Args...>>
{
  typedef typename TypeWithList<T, Args...>::type type;
};

The name TypeWithList stems from the fact that the type is now instantiated with a previous list.


This is a variation of GManNickG's neat partial specialization trick. No delegation, and you get more type safety by requiring the use of your variadic_typedef struct.

#include <tuple>

template<typename... Args>
struct variadic_typedef {};

template<typename... Args>
struct convert_in_tuple {
    //Leaving this empty will cause the compiler
    //to complain if you try to access a "type" member.
    //You may also be able to do something like:
    //static_assert(std::is_same<>::value, "blah")
    //if you know something about the types.
};

template<typename... Args>
struct convert_in_tuple< variadic_typedef<Args...> > {
    //use Args normally
    typedef std::tuple<Args...> type;
};

typedef variadic_typedef<int, float> myTypes;
typedef convert_in_tuple<myTypes>::type int_float_tuple; //compiles
//typedef convert_in_tuple<int, float>::type int_float_tuple; //doesn't compile

int main() {}

참고URL : https://stackoverflow.com/questions/4691657/is-it-possible-to-store-a-template-parameter-pack-without-expanding-it

반응형