Specialization of the template by another template (of the same class)

I am writing an array class. This array class can contain arrays again as members. When implementing the print function, I need specializations.

26:template <class T> class array : public vector<T>{
public:
    ...
       string* printToString();
    ...
};
...           
template <class T> string* array<T>::printToString(){
   ...  // generic function
}
template <> inline string* array<double>::printToString(){
   ...  // spezialization for double, works
}
561:template <class U> string* array<array<U>*>::printToString(){
   ...  // does not work
}

The last definition expresses

src/core/array.h:561: error: invalid use of incomplete type ‘class array<array<T> >’
src/core/array.h:26: error: declaration of ‘class array<array<T> >’

The g ++ version is g ++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3, if that matters. Any ideas what the problem is?

Thanks in advance Thomas

+5
source share
3 answers

As an alternative to David's solution, you can unconditionally redirect the call to many overloaded functions:

template <class T> class array;
namespace details {
  template <class T> std::string array_print(array<T> const&);
  std::string array_print(array<double> const&); // Regular function 
  template <class T> std::string array_print(array<array<T> > const&);
}

template <class T> class array : private vector<T> {
public:
    ...
       std::string printToString() { return details::array_print(*this); }
    ...
};

namespace details { /* implementions after class is defined */ }
+4
source

, , double, array<U>, U - .

, , , .

namespace detail {
   template <typename T>
   struct array_printer {
      static std::string print( array<T> const & array ) {
         // basic implementation
      }
   };
   template <typename T>
   struct array_printer< array<T> > {
      static std::string print( array< array<T> > const & array ) {
         // specialization for array<T>
      }
   }
}

- :

template <typename T> 
class array : std::vector<T> {  // do not publicly derive from STL containers
public:
   std::string printToString() const {
      return detail::array_printer<T>::print( *this );
   }
}

, , , , .

+3

. :

// Fully specialized. You cannot replace `double` with generic parameter.
template <>
string* array<array<double>*>::printToString(){
    return nullptr;
}

. :

template <class T> class array : public vector<T>{
public:
    string* printToString();
};

template <class T> string* array<T>::printToString(){
    return nullptr;
};

// Partial specialization.
template <class T> class array<array<T>*> : public vector<T>{
public:
    string* printToString();
};

template <class T> string* array<array<T>*>::printToString(){
    return nullptr;
};

- EDIT ---

"" . "" . ...

template <class T> class array : public vector<T>{
public:
    string* printToString();
    void f();
};

// (1a)
template <class T> string* array<T>::printToString(){
    return nullptr;
};

// (2)
template <class T> void array<T>::f(){
};

template <class T> class array<array<T>*> : public array<T> {
public:
    string* printToString();
};

// (1b)
template <class T> string* array<array<T>*>::printToString(){
    return nullptr;
};

void Test() {

    array<double> a1;
    a1.printToString(); // Calls (1a).
    a1.f(); // Calls (2).

    array<array<char>*> a2;
    a2.printToString(); // Calls (1b).
    a2.f(); // Calls (2).

}

... which may or may not be what you need (you may need some “manual” repetition).

+1
source

All Articles