2017-09-24 95 views
3

我会尽量简单解释我目前的问题。它可以很容易地解决,但我迄今发现的唯一解决方案并不能满足自己,也许你会向我表明解决方案需要的下一级间接性。C++模板声明限制专业化太多

我在这里使用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> >会有两个,等等......)。 我失败的地方在于它在专业化之前对C的声明,因为我不知道如何声明足够通用的东西来支持值和类型模板参数(在本例中为int值和类型,混合)。 因为如果我宣布

template <typename ... Args> 
class C; 

它显然无法解析整数。

而且

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

显然无法解析类型的专业化只有一个int参数。

所以,我发现到现在为止唯一的解决办法是宣布2种不同类型,而不是C

template <int a, typename ... Args> // allows first specialisations 
class C; 
template <int a, int b, typename ... Args> //allows second specialisations 
class D; 

但我想组进只有一个声明。可能吗 ?

预先感谢您! PS:顺便说一下,我选择的标题是非常糟糕的,如果你有更好的建议,让我知道!

回答

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; 
} 
+0

而如何实例'C '在这种情况下?类似于'C <1> c;'可能会产生错误。 – VTT

+0

@VTT - 旧的'C <1> c;'成为'C > c;';或许是在答案中加入了这一点;谢谢。 – max66

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