There is no likely reason for that certain error, unless perhaps there is a class child predeclared without a class template.
One cause may be that you should initialise a member using () rather than {}:
child(std::vector<T> arg)
: _arg{arg}
{
}
should be corrected to:
child(std::vector<T> arg)
: _arg(arg)
{
}
It's also better to pass by const reference:
child(const std::vector<T>& arg)
: _arg(arg)
{
}
However, there are a couple of other things that may be improved to aid the program:
The for loop will not compile:
for(std::vector<T>::iterator it = _arg.begin(); it != _arg.end(); ++ it)
{
method2(voidp, *it);
}
T is a dependent name which means that std::vector<T>::iterator should be corrected to typename std::vector<T>::iterator. You can read more about this here.
However, std::vector<T>::iterator should also be corrected to std::vector<T>::const_iterator. As the function method is const, the const means that the function will promise not to modify any of the members of the class. However, the iterator begin() function in the vector is not const-qualified which means that the compiler does not know whether you want to modify the members or not. As a result the overload const_iterator begin() const has to be used so that the compiler explicitly knows you will not modify any members.
Another note: if you are using c++11, you can make the loop a lot shorter by using the range-for loop:
for(const auto& x : _arg)
{
method2(voidp, x);
}
There is no need to declare public: twice in the class; once public has been declared once, everything following will be public until the compiler reaches another protected/private keyword, and vice-versa for the other keywords.
Note that the default access level for a class is private and is public for a struct. Thus your class can be slightly amended to this:
template<typename T>
class child : public base<T>
{
public:
child(const std::vector<T>& arg)
: _arg(arg)
{
}
virtual ~child() {}
void method(const void* voidp) const
{
for(typename std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++ it)
{
method2(voidp, *it);
}
}
protected:
std::vector<T> _arg;
};
Same for your base class:
template<typename T>
class base
{
protected:
base() {}
virtual ~base() {}
virtual void method(const void* voidp) const = 0;
};
Be consistent with where you put the const keyword in your function declarations:
You have: void* const voidp and then const double& arg. As shown, the const keyword is inconsistently placed - one after and one before the type:
It would be better to do either: const void* voidp, const double& arg or void* const voidp, double const& arg for consistency.
To finish, I compiled the below code using MSVC and it worked fine:
template<typename T>
class base
{
protected:
base() {}
virtual ~base() {}
virtual void method(const void* voidp) const = 0;
};
template<typename T>
class child : public base<T>
{
public:
child(const std::vector<T>& arg)
: _arg(arg)
{
}
virtual ~child() {}
void method(const void* voidp) const
{
for(typename std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++it)
{
method2(voidp, *it);
}
}
protected:
std::vector<T> _arg;
};
Hope this helps:)