简体   繁体   English

专门为一种类型的模板类成员函数

[英]Specializing a template class member function for only one type

I have a template class that has lots of functions but is essentially a vector class. 我有一个模板类,它有很多功能,但本质上是一个矢量类。 I want to add one function to just the bool type. 我想为bool类型添加一个函数。

#include <vector>
template <typename T>
class reflected{
    private:
        T*dev_;
        T*host_;
        ar_size size;
        reflected<T>& operator=(reflected<T>& rhs);//do not impliment.  assign not allowed.
        reflected( reflected<T>& old);  //do not impliment. Copy not allowed.
    public:
        reflected():size(0L),dev_(NULL),host_(NULL){}
        reflected(ar_size n):size(n),dev_(NULL),host_(NULL){init();}
        reflected(const T*x,ar_size n):size(n),dev_(NULL),host_(NULL){init();set(x);}
        ~reflected();
        void init();
        void init(ar_size n);
        void init(const T*x,ar_size n);
        void set(const T * x);
        void setat(ar_index i, T x);
        const T getat(ar_size i);
        const T * devPtr();
        const T operator [](const ar_index i);
        ar_size length(){return size;}
};

I want to add a function vector<ar_index> reflected<bool>::which() to the special case of the reflected class, which is the only case where it would make sense. 我想在反射类的特殊情况下添加一个函数vector<ar_index> reflected<bool>::which() ,这是唯一有意义的情况。 What is the best way to do this. 做这个的最好方式是什么。 the compiler seems to not like adding which() to reflected and only defining it for bool. 编译器似乎不喜欢添加which()来反映并仅为bool定义它。

You can define it in the class template like this 您可以在类模板中定义它

template <typename T> struct id { typedef T type; };

template <typename T>
class reflected{
    private:
        /* ... */
        vector<ar_index> which(id<bool>) { 
          /* ... */
        }
    public:
        /* ... */
        vector<ar_index> which() { return which(id<T>()); }
};

This gives a compile time error if you call which on a reflected<T> for whose T you haven't given the proper definition. 如果您在reflected<T>上调用which T您没有给出正确的定义,则会产生编译时错误。

If you want to add just one question, you can combine inheritance with specialization: 如果您只想添加一个问题,可以将继承与专业化结合起来:

template <typename T>
class reflected_base { 
    // your current 'reflected' contents go here
}; 

template <typename T>
class reflected : public reflected_base { };

template <>
class reflected<bool> : public reflected_base {
    vector<ar_index> which();
};

The downside of this approach is that you have to reimplement certain operations (destructors, copy constructors, etc.) for each specialization. 这种方法的缺点是你必须为每个专业化重新实现某些操作(析构函数,复制构造函数等)。 Another option would be: 另一种选择是:

template <typename T>
class specialized_reflected { };

template <>
class specialized_reflected<bool> {
public:
    vector<ar_index> which();
};

template <typename T>
class reflected : public specialized_reflected<T> {
    // your current 'reflected' contents go here
};

Though, then there are potential issues with dependent name lookup. 但是,依赖名称查找存在潜在问题。 A third option (and probably the one I would choose) would be to use a non-member function: 第三个选项(可能是我选择的选项)是使用非成员函数:

vector<ar_index> which(reflected<bool>&);

Can't be done directly the way you want. 不能以你想要的方式直接完成。 But you can achieve a similar result by not defining reflected() for any class except the specialized one. 但是你可以通过不为任何类定义reflected()来实现类似的结果,除了专门的类。 Then you will get a liner error if you try to use it on a non-supported class. 如果您尝试在不受支持的类上使用它,则会出现线性错误。

#include <string>
#include <sstream>
using namespace std;

template<typename A>
class Gizmo
{
public:
    Gizmo(){};
    int which();    
};

template<> int Gizmo<bool>::which()
{
    return 42;
}

int main()
{

    Gizmo<bool> gb;
    gb.which();

    Gizmo<int> gi;
    gi.which(); // LINKER ERROR for Gizmo<int>which()

    return 0;
}

You can add vector<ar_index> reflected<bool>::which() to reflected<bool> (and only to it, not to the general template). 您可以将vector<ar_index> reflected<bool>::which()reflected<bool> (仅限于它,而不是通用模板)。 If you get an error, maybe you're not doing the template specialization correctly... 如果您收到错误,也许您没有正确地进行模板专业化...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM