0

I'm using static polymorphism (CRTP method) to create class hierarchy. The idea is to use a struct defined in derived class in base one. However, VC10 generates following error:

error C2039: 'param_t' : is not a member of 'D'

and Intel C++ generates following error:

error : incomplete type is not allowed

It's quite confusing that Derived::param_t is a struct type and shall be compiled normally. Please point out the problem in the code. Thanks.

// Base class
template<typename Derived>
struct Base {
  typedef typename Derived::param_t param_t; //error c2039

  void setParam(param_t& param);
  const param_t& getParam() const;
  ...

};

// Derived class
class D: public Base<D> {
public:
  struct param_t {
    double a, b, c;
  };

  D(param_t& param):param_(param) {}
  ...

protected:
  param_t param_;   

};

int main()
{
  D::param_t p = {1.0, 0.2, 0.0};
  D *pD = new D(p);
}
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • 1
    Can you show all references to `param_t` in `Base`? – Angew is no longer proud of SO May 06 '13 at 13:50
  • 3
    possible duplicate of [C++ static polymorphism (CRTP) and using typedefs from derived classes](http://stackoverflow.com/questions/6006614/c-static-polymorphism-crtp-and-using-typedefs-from-derived-classes) – TemplateRex May 06 '13 at 13:53
  • Hi Welcome to StackOverflow! Make sure to read the [FAQ](http://stackoverflow.com/faq), in particular on how to research your questions before posting them. E.g. searching for "CRTP incomplete type" would have given you plenty of information. – TemplateRex May 06 '13 at 13:59
  • Sorry for posting duplicate topic. The solution is a trait class or a template member function 'setParam' 'getParam'. I prefer latter, because the 'struct' definition shall be inside 'class D' for encapsulation purpose. Thanks for all help and suggestions. – seanxnie May 08 '13 at 01:03

1 Answers1

0

You can't use types from derived class in base class definition. You can use it only inside bodies of member functions. The problem is that typedef typename Derived::param_t param_t is resolved for class D: public Base<D> when compiler doesn't know yet about nested types of D. Member functions are compiled after actual instantiation of D when definition of D is available.

I think in your case you can't use CRTP method.

ArmanHunanyan
  • 905
  • 3
  • 11
  • 24