8

I have this class template

template <typename T>
class Wrapper
{
    public:
        virtual void parse(std::string s) = 0;

    protected:
        T value;
};

ideally, each type should know how to parse itself from a string, so I would like to have, for instance, specializations such as

template<>
class Wrapper<int> 
{
    public:
        virtual void parse(std::string s) 
        {
            value = atoi(s.c_str());
        }
};

however, apparently, I can't access the "value" member from the main template. What I get is something like:

In member function 'virtual void Wrapper<int>::parse(std::string)':
error: 'value' is not a member of 'Wrapper<int>'

adding this-> in front of value doesn't help.

Do you have any idea how to fix this?

Thanks

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
tunnuz
  • 23,338
  • 31
  • 90
  • 128

2 Answers2

6

The various specializations of class template are completely unrelated to each other. Wrapper<int> does not know anything about e.g. Wrapper<char>. So you need to separately define the data members for each specialization

template<>
class Wrapper<int> 
{
    public:
        virtual void parse(std::string s) 
        {
            value = atoi(s.c_str());
        }
    protected:
        int value;
};

There is also the question of the virtual keyword in front of parse(). You do not need it here unless you intend Wrapper<int> to be a base class that can have its parse() method redefine by subsequent derived classes. If all you are going to do is create various Wrapper<> specializations, then you should not make parse() virtual.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • @tunnuz and similarly about the `protected` keyword here: you do not seem to need it, and in general it is not recommended to have such data anyway. Just make your data `private`. – TemplateRex Sep 19 '13 at 14:41
  • hmmm, if the template specialization class would have to re-define all its own data members and methods, I'd doubt why not just write a completely new class? – avocado Oct 13 '17 at 06:42
4

I think I solved it, the trick is to specialize only the member functions, not the whole class

template<>
void Wrapper<int>::parse(std::string s)
{
    this->value = atoi(s.c_str());    
}
tunnuz
  • 23,338
  • 31
  • 90
  • 128
  • 2
    this works, but only for full specializations, not for partial specializations (e.g. not for `std::vector`, or `T*`) – TemplateRex Sep 19 '13 at 14:40