C ++模板声明过多地限制了特化

时间:2017-09-24 16:34:53

标签: c++ c++11 templates variadic-templates specialization

我会试着简要解释一下我目前的问题。它可以很容易地解决,但我到目前为止找到的唯一解决方案并不能满足我自己,也许你会向我指出解决方案所需的下一级间接。

我在这里使用CRTP,即使这不是问题的症结所在。这是一段代码,可以重现我的问题:

template <typename T>
class A
{
    public:
        static void p()
        {
            T::p();
        }
};

template <typename T>
class B
{
    public:
        static void q()
        {
            T::q();
        }
};



????? template <??????> ???? // How to declare C here ??? 
class C;


//now first specializations with A
template <int a>
class C<a> : public A<C<a> >
{
    public:
        static void p()
        {
            //specific stuff
        }
};

template <int a, typename Other_handlers ...>
class C<a, Other_handlers...> : public A<C<a, Other_handlers...> >
{
    public:
        static void p()
        {
            //specific stuff
        }
};

template <int a, typename Child>
class C<a, B<Child> > : public A<C<a, B<Child> > >
{
    public:
        static void p()
        {
            //specific stuff
        }
};



//second specializations with B
template <int a, int b>
class C<a, b> : public B<C<a, b> >, C<a>
{
    public:
        static void q()
        {
            //specific stuff
        }
};

template <int a, int b, typename Other_handlers ...>
class C<a, b, Other_handlers...> : public B<C<a, b, Other_handlers...> >, C<a>
{
    public:
        static void q()
        {
            //specific stuff
        }
};

template <int a, int b, typename Child>
class C<a, b, B<Child> > : public B<C<a, b, B<Child> > >, C<a>
{
    public:
        static void p()
        {
            //specific stuff
        }
};

这段代码的目标是在C中使用一些取决于模板参数的方法(此处C<1,2>将包含AB的方法虽然C<1>只有A,但C<1, C<1,2> >只有A,而C<1, 2, C<3> >会同时拥有template <typename ... Args> class C; 等等。 )。 我失败的地方在于C专业化之前的声明,因为我不知道如何声明一些通用的东西足以支持值和类型模板参数(在这种情况下是int值和类型,混合)。 因为如果我宣布

template <int a, int b, typename ... Args>
class C;

显然无法解析整数。

int

显然无法仅使用一个C参数解析特化中的类型。

所以,我到目前为止找到的唯一解决方案是声明2种不同类型而不是template <int a, typename ... Args> // allows first specialisations class C; template <int a, int b, typename ... Args> //allows second specialisations class D;

echo "<td><a href='stats_game.php?idGame=".$row['idGame']."'>".$row['result']."</a></td>";      

但我想只分成一个宣言。有可能吗?

提前谢谢!

PS:顺便说一下,我选择的标题非常糟糕,如果你有任何更好的建议,请告诉我!

2 个答案:

答案 0 :(得分:1)

我能想象的最好的事情是将C声明为仅接收类型

template <typename ...>
class C;

并将初始整数值包装在虚拟类型中(或使用std::integer_sequence

template <int ...>
struct Ci
 { };

显然是C声明(例如)C<1>,之前

C<1> c1;

成为

C<Ci<1>> c1;

以下代码很难看,但编译

template <typename> class A {};
template <typename> class B {};

template <typename ...>
class C;

template <int ...> struct Ci {};

template <int a>
class C<Ci<a>> : public A<C<Ci<a>>>
 { };

template <int a, typename ... Other_handlers>
class C<Ci<a>, Other_handlers...> : public A<C<Ci<a>, Other_handlers...>>
 { };

template <int a, typename Child>
class C<Ci<a>, B<Child>> : public A<C<Ci<a>, B<Child>>>
 { };

template <int a, int b>
class C<Ci<a, b>> : public B<C<Ci<a, b>> >, C<Ci<a>>
 { };

template <int a, int b, typename ... Other_handlers>
class C<Ci<a, b>, Other_handlers...>
   : public B<C<Ci<a, b>, Other_handlers...>>, C<Ci<a>>
 { };

template <int a, int b, typename Child>
class C<Ci<a, b>, B<Child> > : public B<C<Ci<a, b>, B<Child> > >, C<Ci<a>>
 { };


int main ()
 {
   C<Ci<1>>  c1;
 }

答案 1 :(得分:0)

我只能想到涉及宏的丑陋解决方案,它只允许您将结果类型用法分组到一个声明中:

template<int V> struct
fooIntImpl
{
};

template<int V> fooIntImpl<V>
foo_deduce_helper(void);

template<typename T> struct
fooTypeImpl
{
};

template<typename T> fooTypeImpl<T>
foo_deduce_helper(void);

#define foo(template_parameters) decltype(foo_deduce_helper<template_parameters>())

int main()
{
    foo(42) fooint;
    foo(int) footype;

    return 0;
}