C++ 部分模板特化:成员函数

mac*_*low 3 c++ templates template-specialization

我有一个模板

template <int a, int b>
class MyTemplateClass
{
    // ....
    void computeSomething();
};
Run Code Online (Sandbox Code Playgroud)

我想部分专注于 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
}
Run Code Online (Sandbox Code Playgroud)

但是,据我所知,部分特化对于成员函数是无效的。我怎样才能实现我想要的?还有其他解决方案吗?谢谢!

max*_*x66 5

一种可能的方法是 estract 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; }
 };
Run Code Online (Sandbox Code Playgroud)

您可以foo通过继承“专门化”计算,如下所示

template <int a, int b>
struct foo : public fooSub<a, b>
 { };
Run Code Online (Sandbox Code Playgroud)

另一种可能的解决方案,如果可以使用至少C ++ 11,是激活/取消激活不同版本的compute()使用SFINAE( std::enable_if)如下面的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; }
 };
Run Code Online (Sandbox Code Playgroud)

遵循两种方式的完整可编译示例

#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
 }
Run Code Online (Sandbox Code Playgroud)