当前位置:编程学习 > C/C++ >>

在C++范型编程中如何只特化类的一个成员函数

我们知道在C++模板编程中如果我们特化或是偏特化某个模板类, 我们需要重写整个模板类中的所有函数, 但是这些代码通常是非常相似的, 甚至在某些情况下可能只有一两个函数会不一样,其他函数都是一样的。在这种情况下,同时存在多份相同的代码,对我们维护这些代码是非常不利的, 我们最好只需要特化其中不一样的那个函数。
 
比如下面这个模板类:
 
 
 
template<typename T, unsigned B>
struct Base
{
    //other function
    //....
    void Func(){ cout << "primary function" << endl; }
};
void test1()
{
    Base<int, 1> a;
    a.Func();
    Base<int, 16> b;
    b.Func();
}
int main()
{
     test1();
}
 
 
 
 
只有当B等于16时, Func这个函数需要特化, 但是其他函数无论什么情况下都是一样的。
 
下面是我们的一些可能解决方案:
 
方法1:
 
 
 
template<typename T>
struct Base<T, 16>
{
    //other function
    //....
    void Func(){ cout << "specialization function" << endl; }
};
 
 
点评:通过偏特化实现,需要重写所有的类成员方法。
 
 
 
方法2:
 
 
 
template<typename T, unsigned B>
struct Base
{
    //other function
    //....
    void Func()
    {
        if(B == 16)
        {
            cout << "primary function" << endl;
        }
        else
        {
            cout << "specialization function" << endl;
        }
    }
};
 
 
点评: 通过运行时判断, 容易理解,但是相对低效。
 
 
 
方法3:
 
 
 
template<typename T, unsigned B>
struct Base
{
    //other function
    //....
    void Func()
    {
#if B!=16
            cout << "primary function" << endl;
#else
            cout << "specialization function" << endl;
#endif
    }
};
 
 
点评: 试图通过预编译来实现,但是这个方法是错误的。C++模板编译包括预编译,语法检查,模板实例化等阶段,在预编译阶段模板参数都还没有实例化呢。
 
 
 
方法4:
 
 
 
template<typename T, unsigned B>
struct Base
{
    //other function
    //....
    template<unsigned S>
    struct FuncObj
    {
        void operator()()
        {
            cout<<"primary function"<<endl;
        }
    };
    template<>
    struct FuncObj<16>
    {
        void operator()()
        {
            cout<<"specialization function"<<endl;
        }
    };
    FuncObj<B> Func;
};
 
 
点评: 通过成员类以防函数的形式特化, 增加了类成员变量。
 
 
 
方法5:
 
 
 
template<typename T, unsigned B>
struct Base
{
    //other function
    //....
    template<unsigned N>
    void FuncImpl()
    {
        cout<<"primary function"<<endl;
    }
    template<>
    void FuncImpl<16>()
    {
        cout<<"specialization function"<<endl;
    }
    void Func()
    {
        FuncImpl<B>();
    }
};
 
 
点评:通过类成员模板函数特化来实现。
 
 
 
方法6:
 
 
 
template<typename T, unsigned B>
struct Base
{
    //other function
    //....
    template<unsigned N> 
    class Int2Type
    {
        enum { value = N };
    };
    template<unsigned V>
    void FuncImpl(const Int2Type<V>)
    {
        cout<<"primary function"<<endl;
    }
    void FuncImpl(const Int2Type<16>)
    {
        cout<<"specialization function"<<endl;
    }
    void Func()
    {
        FuncImpl(Int2Type<B>());
    }
};
 
 
点评: 通过将int根据值的不同转成不同的类型,然后通过函数重载实现。
 
 
 
方法7:
 
 
 
namespace
{
    template <bool,typename T,typename> struct conditional { typedef T type; };
    template <typename T,typename U> struct conditional<false,T,U> {typedef U type; };
}
template<class T, unsigned B>
struct Base
{
    //other function
    //....
 
    void Func ()
    {
        typedef typename ::conditional<B!=16,primary_t,spec_t>::type type;
        Func_impl(type());
    }
private:
    struct primary_t { };
    struct spec_t    
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,