Question

I'm having a problem with a Template specialization since I don't want to redefine a method, I want to use the generic one.

template<class VarsContainer, class Specific>
class State
{
public:
  State();
  ~State(){}

  HSError_t Update(LoggerData const &lData);
  VarsContainer state;

  void swap(State &rhs);
  State & operator=(State rhs); // pass by value copy

protected:
  void UpdateSpecific(Specific *rhs);
  Specific specificPtr;
};

And in the implementation I do the following:

template<class VarsContainer, class Specific>
HSError_t State<VarsContainer, Specific>::Update(LoggerData const &lData)
{
  HSError_t error_t = HeatInterfaceError;
  specificPtr = const_cast<Specific>(&lData);
  error_t = UpdateSpecific(specificPtr);
  if(error_t != HeatSuccess)
  {
    return error_t;
  }
  return error_t;
}

template<class VarsContainer, class Specific>
HSError_t State<VarsContainer, Specific>::UpdateSpecific(Specific *rhs)
{
  HSError_t error_t = HeatInterfaceError;
  return error_t;
}

After doing that I specialize the template in the following manner:

template<>
class State<ChemicalVars, Chemicals*>
{
public:
  ChemicalVars state;

protected:
  HSError_t UpdateSpecific(Chemicals *chemicals);
  Chemicals *specificPtr;
};

And I define UpdateSpecific in a cpp file copying data from the specialized struct to the local state.

Problem is that when I try to call the "Update" method the compiler does not created a definition for it in my specialized template of ChemicalVars.

Afterwards I change my specialization with:

template<>
class State<ChemicalVars, Chemicals*>
{
public:
  ChemicalVars state;
  HSError_t Update(LoggerData const &lData);

protected:
  HSError_t UpdateSpecific(Chemicals *chemicals);
  Chemicals *specificPtr;
};

But still, the error is the same:

undefined reference to `State<ChemicalVars, Chemicals*>::Update(LoggerData const&)'

Problem is the generic implementation is good, I just want to use the one defined in the Generic State to be used by the specializations.

Was it helpful?

Solution 2

Specializing a class template means that whenever that class is instantiated with that specific specialized type, it will use the specialized definition. That is the reason you got the first undefined error. But when you added the specialized update function but did not defined it, instead assumed it to use the default one, then that caused the second error message you got because it does not use the default one as you wished, but instead tries to look for the specialized Update definition. I think what you want todo is a little bit more abstraction like so:

//This will hold all function common to template param for State class
template<typename Container, typename Specific>
struct CommonStateDefinition{  
     void Update(StructData const &lData){
         std::cout<<"In CommonStateDefinition::Update" << endl;
     }
};

template<typename Container, typename Specific>
struct State{
    CommonStateDefinition<Container,Specific> m_stateImpl;
    void Update(StructData const &lData){
        std::cout << "In State::Update" << endl;
        m_stateImpl.Update(lData);
    }
}

template<>
class State<ChemicalVars, Chemicals*>{
    CommonStateDefinition<ChemicalVars,Chemicals*> m_stateImpl;
    //use the common update via delegation
    void Update(StructData const &lData){
        std::cout << "In State<ChemicalVars,Chemicals*>::Update" << endl;
        m_stateImpl.Update(lData);
    }
    //add other specialized function
}

OTHER TIPS

The definitions of the specialization and the base template are somehow unrelated. The specialization does not inherit anything from the base template, you would have to redefine all functions in the base template that you need.

The common workaround is to split the base template into a base class that has all of the code that is common to all specializations and then inherit from there in the base template and the specializations so that the common code can be reused.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top