模板部分专业化:如何避免代码重复?

Gid*_*dle 8 c++ templates partial-specialization

当模板完全专用时,不需要复制成员函数.例如,在以下代码中,foo()只写入一次.

#include <iostream>

template<int M>   
class B
{              
public:
    void foo();   
private:
    void header();
};         

template<int M>   
void          
B<M>::foo()
{
    // specialized code:              
    header();
    // generic code:
    std::cout << "M = " << M << std::endl;             
}                   

template<int M>                                                             
void                                                                        
B<M>::header()                                                              
{                                                                           
    std::cout << "general foo()" << std::endl;                              
}                                                                           

template<>                                                                  
void                                                                        
B<2>::header()                                                              
{                                                                           
    std::cout << "special foo()" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是,对于部分特化,有必要复制类定义和所有成员函数.例如:

#include <iostream>

template<int M, int N>
class A
{                  
public:   
    void foo();   
private:
    void header();
};     

template<int M, int N>
void              
A<M, N>::foo()
{          
    // specialized code:
    header(); 
    // generic code:
    std::cout << "M = " << M << ", N = " << N << std::endl;
}                                     

template<int M, int N>
void                                                   
A<M, N>::header()   
{                                                                           
    std::cout << "general foo()" << std::endl;                              
}                                                                           

template<int N>                                                             
class A<2, N>                                                               
{                                                                           
public:                                                                     
    void foo();                                                             
private:                                                                    
    void header();                                                          
};                                                                          

template<int N>                                                             
void                                                                        
A<2, N>::foo()                                                              
{                                                                           
    // specialized code:                                                    
    header();                                                               
    // generic code:                                                        
    std::cout << "M = " << 2 << ", N = " << N << std::endl;                 
}                                                                           

template<int N>
void                                                                        
A<2, N>::header()                                                           
{                                                                           
    std::cout << "special foo()" << std::endl;                              
}
Run Code Online (Sandbox Code Playgroud)

请注意,手动替换为2 A<2, N>::foo()的副本.A<M, N>::foo()M

在模板部分特化的上下文中,如何避免这种代码重复?

m.s*_*.s. 1

您可以header进入一个单独的班级,并且仅部分专业化这一班级:

#include <iostream>

template <int M, int N>
struct Header
{
    static void header()
    {
        std::cout << "general foo()" << std::endl;
    }
};

template <int N>
struct Header<2, N>
{
    static void header()
    {
        std::cout << "special foo()" << std::endl;
    }
};

template<int M, int N>
struct A
{                  
    void foo();
};     

template<int M, int N>
void              
A<M, N>::foo()
{          
    Header<M,N>::header(); 
    std::cout << "M = " << M << ", N = " << N << std::endl;
}

int main()
{
    A<1,1> a11;
    a11.foo();

    A<2,5> a25;
    a25.foo();
}
Run Code Online (Sandbox Code Playgroud)

输出

general foo()
M = 1, N = 1

special foo()
M = 2, N = 5
Run Code Online (Sandbox Code Playgroud)

live example