3

I am trying to call the Size() function of base class Array. The error from Clang is "use of undeclared identifier 'Size'". Below is my header for NumericArray, function definition in source file, and function definition in base class. Many thanks for the help.

derived header

#ifndef NUMERICARRAY_H
#define NUMERICARRAY_H
#include "array.h"

namespace Cary
{
    namespace Containers
    {
        template<typename T>
        class NumericArray: public Array<T>
        {
        public:
            NumericArray<T>();    //default constructor
            ~NumericArray<T>();    //destructor
            NumericArray<T>& operator = (const NumericArray<T>& array1);    //assignment operator
            NumericArray<T>& operator * (double factor) const;    //scale
            NumericArray<T>& operator + (const NumericArray<T>& array1) const;    //add
        };
    }
}
#endif

function definition in cpp

template<typename T>
        NumericArray<T>& NumericArray<T>::operator * (double factor) const    //scale
        {
            NumericArray<T> scale(Size());
            for (int i = 0; i < Size(); i++)
                scale[i] = factor * ((*this).GetElement(i));
            return scale;
        }

size function from base class

template<typename T>
        int Array<T>::Size() const    //returns size
        {
            return m_size;
        }
vsoftco
  • 55,410
  • 12
  • 139
  • 252
kits
  • 609
  • 6
  • 20
  • Unrelated to your error, but those implementations should probably be in header files too. http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – T.C. Feb 15 '15 at 01:59
  • They're in headers don't worry thanks! – kits Feb 15 '15 at 02:03

1 Answers1

11

You need to use this->Size(), this is a bit awkward, but that's how C++ works. When you derive from a template class, the compiler doesn't look at the members of the template base at declaration point (basically, at declaration, the base part is un-instantiated, and it is a bit painful for the compiler to figure out if the function is defined in the base class). So the default behaviour is to not look in in the scope of template base classes.

Alternatively, you can as well use using Array<T>::Size; to tell the compiler that the the base class contains indeed the function Size().

Or, as a last alternative, can explicitly call Array<T>::Size(). However this alternative is not recommended whenever you deal with virtual functions, since you lose the ability to using them polymorphically.

BTW, there is a whole chapter (Item 43) in Effective C++ by Scott Meyers (see The Definitive C++ Book Guide and List) dedicated to this issue.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Thanks vsoftco. The error is this line in the source file definition. I don't think I can implement 'this' here. NumericArray scale(Size()); – kits Feb 15 '15 at 02:02
  • @kits Just do `NumericArray scale(this->Size())`, as I told you, by default C++ doesn't look in the scope of template base classes. Using `this` is a guarantee for the compiler that `Size()` is defined. – vsoftco Feb 15 '15 at 02:08
  • This is great. Thanks for your help. The error is gone! – kits Feb 15 '15 at 02:13
  • Whenever you have a 'weird' error with template code, chances are it needs a bit of hand holding to understand what you're talking about. There is always the possibility someone uses template<> to specialize a template with completely different semantics than the "generic" version. This is a way of saying, "_yeah, I know, Array may not have a `Size() const` method, but I need one, if that fails feel free to bark at me_". – ZaldronGG Feb 15 '15 at 03:34