C++ C++;部分模板专门化:成员函数
我有一个模板C++ C++;部分模板专门化:成员函数,c++,templates,template-specialization,C++,Templates,Template Specialization,我有一个模板 template <int a, int b> class MyTemplateClass { // .... void computeSomething(); }; 模板 类MyTemplateClass { // .... void computeSomething(); }; 我想专门针对b的两种特殊情况: template<int a> void MyTemplateClass<a, 2> :: computeSome
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething();
};
模板
类MyTemplateClass
{
// ....
void computeSomething();
};
我想专门针对b的两种特殊情况:
template<int a>
void MyTemplateClass<a, 2> :: computeSomething()
{
// Special case for b=2 here
}
template<int a>
void MyTemplateClass<a, 3> :: computeSomething()
{
// Special case for b=3 here
}
模板
void MyTemplateClass::computeSomething()
{
//这里是b=2的特例
}
模板
void MyTemplateClass::computeSomething()
{
//这里是b=3的特例
}
然而,据我所知,部分专门化对于成员函数是无效的。我怎样才能实现我想要的?还有其他解决办法吗?谢谢大家! 由于模板的类型名是已知的,您可以在
computeSomething
函数中添加一些实现来分支流,如下所示:
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething()
{
if (b == 2) { computeWith2(); }
else if (b == 3) { computeWith3(); }
else { computerNormally(); }
};
}
模板
类MyTemplateClass
{
// ....
void computeSomething()
{
如果(b==2){computeWith2();}
如果(b==3){computeWith3();}
else{computerNormally();}
};
}
一种方法是将该类中的计算提取到一个单独的类中
然后,您只能专门研究该计算类:
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething() {
Computation<a, b> c;
c.compute();
}
};
template <int a, int b>
struct Computation { void compute () {} };
template <int a>
struct Computation<a, 2> { void compute () {} };
template <int a>
struct Computation<a, 3> { void compute () {} };
模板
类MyTemplateClass
{
// ....
void computeSomething(){
计算c;
c、 compute();
}
};
模板
结构计算{void compute(){};
模板
结构计算{void compute(){};
模板
结构计算{void compute(){};
虽然在我看来,最好不要使用专门化,而是使用不同的(描述性的!)名称和编译时条件来选择它们:
template<bool Condition,
typename Then,
typename Else>
using if_t = typename std:: conditional<
Condition, Then, Else>:: type;
template <int a, int b>
class MyTemplateClass
{
// ....
using Computation =
if_t<b == 2,
B2Comp<a>,
if_t<b == 3,
B3Comp<a>,
DefaultComp<a, b> > >;
void computeSomething() {
Computation c;
c.compute();
}
};
// Add (template) classes, B3Comp and DefaultComp
模板
使用if_t=typename std::conditional<
条件,然后,Else>::类型;
模板
类MyTemplateClass
{
// ....
使用计算=
如有,;
void computeSomething(){
计算c;
c、 compute();
}
};
//添加(模板)类、B3Comp和DefaultComp
如果您已经可以尝试C++17,则可以将上述内容重写为:
template <int a, int b>
class MyTemplateClass
{
// ....
void computeSomething() {
if constexpr (b == 2) {
B2Comp<a> comp;
comp.compute();
} else if constexpr (b == 3) {
B3Comp<a> comp;
comp.compute();
} else {
DefaultComp<a, b> comp;
comp.compute();
// Or just put the code here, if it's short
}
}
};
模板
类MyTemplateClass
{
// ....
void computeSomething(){
如果constexpr(b==2){
B2Comp;
compute();
}如果constexpr(b==3),则为else{
B3Comp-comp;
compute();
}否则{
违约补偿补偿;
compute();
//或者只要把代码放在这里,如果短的话
}
}
};
也可以使用模板函数代替模板类
与使用普通if相反,这避免了对“不需要的”代码路径的评估,从而使放置其他路径成为可能 那里的代码格式不正确(类似于同一模板的递归实例化)。一种可能的方法是分离
compute()
,仅为其创建基类并专门化该基类
我是说。。。如果为fooSub
template <int a, int b>
struct fooSub
{
void compute ()
{ std::cout << "- foo generic compute()" << std::endl; }
};
template <int a>
struct fooSub<a, 2>
{
void compute ()
{ std::cout << "- foo compute() for 2" << std::endl; }
};
template <int a>
struct fooSub<a, 3>
{
void compute ()
{ std::cout << "- foo compute() for 3" << std::endl; }
};
如果您至少可以使用C++11,另一种可能的解决方案是使用SFINAE(std::enable_if
)激活/停用不同版本的compute()
,如下面的bar
类所示
template <int a, int b>
struct bar
{
template <int bb = b>
typename std::enable_if<(b == bb) && (b != 2) && (b != 3)>::type
compute ()
{ std::cout << "- bar generic compute()" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 2)>::type compute ()
{ std::cout << "- bar compute() for 2" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 3)>::type compute ()
{ std::cout << "- bar compute() for 3" << std::endl; }
};
模板
结构条
{
模板
typename std::enable_if::type
计算()
{std::您是否需要部分地专门化整个类,或者创建几个重载的模板方法来处理特定的主类专门化。
template <int a, int b>
struct bar
{
template <int bb = b>
typename std::enable_if<(b == bb) && (b != 2) && (b != 3)>::type
compute ()
{ std::cout << "- bar generic compute()" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 2)>::type compute ()
{ std::cout << "- bar compute() for 2" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 3)>::type compute ()
{ std::cout << "- bar compute() for 3" << std::endl; }
};
#include <iostream>
#include <type_traits>
template <int a, int b>
struct fooSub
{
void compute ()
{ std::cout << "- foo generic compute()" << std::endl; }
};
template <int a>
struct fooSub<a, 2>
{
void compute ()
{ std::cout << "- foo compute() for 2" << std::endl; }
};
template <int a>
struct fooSub<a, 3>
{
void compute ()
{ std::cout << "- foo compute() for 3" << std::endl; }
};
template <int a, int b>
struct foo : public fooSub<a, b>
{ };
template <int a, int b>
struct bar
{
template <int bb = b>
typename std::enable_if<(b == bb) && (b != 2) && (b != 3)>::type
compute ()
{ std::cout << "- bar generic compute()" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 2)>::type compute ()
{ std::cout << "- bar compute() for 2" << std::endl; }
template <int bb = b>
typename std::enable_if<(b == bb) && (b == 3)>::type compute ()
{ std::cout << "- bar compute() for 3" << std::endl; }
};
int main()
{
foo<0, 1>{}.compute(); // print - foo generic compute()
foo<1, 2>{}.compute(); // print - foo compute() for 2
foo<2, 3>{}.compute(); // print - foo compute() for 3
bar<2, 1>{}.compute(); // print - bar generic compute()
bar<3, 2>{}.compute(); // print - bar compute() for 2
bar<4, 3>{}.compute(); // print - bar compute() for 3
}