Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template partial specialization - specializing one member function only

Bumped into another templates problem:

The problem: I want to partially specialize a container-class (foo) for the case that the objects are pointers, and i want to specialize only the delete-method. Should look like this:

The lib code

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
};

template <typename T>
class foo <T *>
{
public:
    void deleteSome (T* o) { printf ("deleting that PTR to an object..."); }
};

The user code

foo<myclass> myclasses;
foo<myclass*> myptrs;

myptrs.addSome (new myclass());

This results into the compiler telling me that myptrs doesnt have a method called addSome. Why ?

Thanx.


Solution

based on tony's answer here the fully compilable stuff

lib

template <typename T>
class foobase
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
};


template <typename T>
class foo : public foobase<T>
{ };

template <typename T>
class foo<T *> : public foobase<T *>
{
public:
    void deleteSome (T* o) { printf ("deleting that ptr to an object..."); }
};

user

foo<int>    fi;
foo<int*>   fpi;

int         i = 13;

fi.addSome (12);            
fpi.addSome (&i);

fpi.deleteSome (12);        // compiler-error: doesnt work
fi.deleteSome (&i);         // compiler-error: doesnt work
fi.deleteSome (12);         // foobase::deleteSome called
fpi.deleteSome (&i);        // foo<T*>::deleteSome called
like image 666
Roman Pfneudl Avatar asked Nov 18 '09 17:11

Roman Pfneudl


People also ask

Can you partially specialize a C++ function template?

You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.

Can a member function be a template?

Member functions can be function templates in several contexts. All functions of class templates are generic but aren't referred to as member templates or member function templates. If these member functions take their own template arguments, they're considered to be member function templates.

What does template <> mean in C ++?

A template is a C++ programming feature that permits function and class operations with generic types, which allows functionality with different data types without rewriting entire code blocks for each type.

What is function template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.


1 Answers

Second solution (correct one)

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); } 
    void deleteSome(T o) { deleteSomeHelper<T>()(o); }
protected:
    template<typename TX> 
    struct deleteSomeHelper { void operator()(TX& o) { printf ("deleting that object..."); } };
    template<typename TX> 
    struct deleteSomeHelper<TX*> { void operator()(TX*& o) { printf ("deleting that PTR to an object..."); } };
};

This solution is valid according to Core Issue #727.


First (incorrect) solution: (kept this as comments refer to it)

You cannot specialize only part of class. In your case the best way is to overload function deleteSome as follows:

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
    void deleteSome (T* o) { printf ("deleting that object..."); }
};
like image 112
Kirill V. Lyadvinsky Avatar answered Sep 24 '22 17:09

Kirill V. Lyadvinsky