C ++ template-function & # 8594; passing a template class as a template argument

I am trying to use templates intensively for the shell of a factory class:

The wrapping class (that is, classA) receives a wrapped class (such as classB) through a template argument to provide "connectivity".

Also, I have to provide an inner class (innerA) that inherits from the wrapped inner class (innerB).

The problem is the following g ++ error message "gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)":

sebastian@tecuhtli:~/Development/cppExercises/functionTemplate$ g++ -o test test.cpp
test.cpp: In static member function ‘static classA<A>::innerA<iB>* classA<A>::createInnerAs(iB&) [with iB = int, A = classB]’:
test.cpp:39:   instantiated from here
test.cpp:32: error: dependent-name ‘classA::innerA<>’ is parsed as a non-type, but instantiation yields a type
test.cpp:32: note: say ‘typename classA::innerA<>’ if a type is meant

As you can see in the definition of the createInnerBs method, I intend to pass a non-type argument. Therefore using typename is wrong!

The test.cpp code is below:

class classB{
public:
  template < class iB>
  class innerB{
    iB& ib;
    innerB(iB& b)
      :ib(b){}
  };

  template<template <class> class classShell, class iB>
  static classShell<iB>* createInnerBs(iB& b){
    // this function creates instances of innerB and its subclasses, 
    // because B holds a certain allocator

    return new classShell<iB>(b);
  }  
};

template<class A>
class classA{
  // intention of this class is meant to be a pluggable interface
  // using templates for compile-time checking
public:
  template <class iB>
  class innerA: A::template innerB<iB>{
    innerA(iB& b)
      :A::template innerB<iB>(b){}
  };

  template<class iB>
  static inline innerA<iB>* createInnerAs(iB& b){
    return A::createInnerBs<classA<A>::template innerA<> >(b); // line 32: error occurs here
  }
};

typedef classA<classB> usable;
int main (int argc, char* argv[]){
  int a = 5;
  usable::innerA<int>* myVar = usable::createInnerAs(a);

  return 0;
}

, , . , ? - ?

,

+3
2

32 :

return A::template createInnerBs<innerA>(b);

createInnerBs A.

innerA innerB public.

+2

:

class classB{ 
public: 
  template < class iB> 
  class innerB{ 
    iB& ib; 
  public:
    innerB(iB& b) 
      :ib(b){} 
  }; 

  template<template <class> class classShell, class iB> 
  static classShell<iB>* createInnerBs(iB& b){ 
    // this function creates instances of innerB and its subclasses,  
    // because B holds a certain allocator 

    return new classShell<iB>(b); 
  }   
}; 

template<class A> 
class classA{ 
  // intention of this class is meant to be a pluggable interface 
  // using templates for compile-time checking 
public: 
  template <class iB> 
  class innerA: public A::template innerB<iB>{ 
  public:
    innerA(iB& b) 
      : A::template innerB<iB>(b){} 
  }; 

  template<class iB> 
  static inline innerA<iB>* createInnerAs(iB& b);
}; 

template<class A> 
template<class iB> 
inline classA<A>::innerA<iB>* classA<A>::createInnerAs(iB& b)
{ 
    return A::template createInnerBs<classA::template innerA>(b);
} 

typedef classA<classB> usable; 
int main (int argc, char* argv[]){ 
  int a = 5; 
  usable::innerA<int>* myVar = usable::createInnerAs(a); 

  return 0; 
} 

, ... .

+1

Source: https://habr.com/ru/post/1748121/


All Articles