Question

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.

#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. What is the best way to do this. the compiler seems to not like adding which() to reflected and only defining it for bool.

Was it helpful?

Solution

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.

OTHER TIPS

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. 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). If you get an error, maybe you're not doing the template specialization correctly...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top