【问题标题】:Deduction of the type of a nested template variadic non-type list嵌套模板可变参数非类型列表的类型推导
【发布时间】:2012-12-27 15:23:37
【问题描述】:

考虑以下类:

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

【问题讨论】:

  • 你的意思是什么可变参数列表?如果您通过MyClassN,则还没有列表。列表只有一个模式,其实例化可能为空,也可能不为空。你的意思是“和 size_t 如果没有参数包”?
  • something&lt;MyClassN&gt;::type 可能会调用另一个结构,例如:template&lt;template&lt;typename, Kind...&gt; class T&gt;。但是如何推导出Kind...

标签: c++ c++11 templates metaprogramming template-argument-deduction


【解决方案1】:

我想不出一种方法来定义 一个通用的 元函数来做到这一点,但这里有一个可能的解决方法:

#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;
}

我尝试只编写一个涵盖所有情况的专业化,如下所示:

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

但是 Clang 3.2 抱怨无法推断出 U 的类型,因此永远不会使用 get_type 的这种特化。因此,如果您遵循这种方法,您将必须明确定义每个专业。这可能会或可能不会接受,具体取决于您的用例。希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2017-05-29
    相关资源
    最近更新 更多