Home > Enterprise >  Template class implementation has compilation issues
Template class implementation has compilation issues

Time:04-08

I am creating an object using static member function of a class. and then calling a function inside.

int main(){
  int a = 49;
  auto foo = Foo::createFoo(a);

  foo->study();
}

Implementation
for this example lets have study() display a value.
Structure wise I do have constraints to have the below interface and then the static method returning the object

class I_Foo{
public:
  virtual void study(void) = 0;
};

class Foo : public I_Foo{
public:
  static Foo* createFoo(int x_) {
    return new Foo(x_);
  }
  
  void study() override{
    std::cout << "studied: "<< st << std::endl;
  }

protected:
  Foo(int a) : st(a) {}

  int st = 0;
};

This above implementation is absolutely working good and as expected i.e., variable a should be displayed as studied: a

Now I want to change the behaviour of this
Lets say for values below 50, the above implementation should remain "unchanged" i.e., variable a should be displayed as studied: a
However as the value becomes 50 and above then the output should display studied: a 100


#include <iostream>

class I_Foo{
public:
  virtual void study(void) = 0;
};

template<int>
class FooImpl;

class Foo : public I_Foo {
public:
  static Foo* createFoo(int x_) {
    
    Foo* foo = nullptr;
    if (x_>=50) {
        foo = new FooImpl<2>(x_);
    }
    else {
        foo = new FooImpl<1>(x_);
    }
    return foo;
  }
};

template<int FT = 1>
class FooImpl : public Foo{
public:

  void study() override{
    std::cout << "studied: "<< st << std::endl;
  }

  FooImpl(int a) : st(a) {}

  int st = 0;
};

template<>
void FooImpl<2>::study() override{
  std::cout << "studied: "<< st   100 << std::endl;
}

int main()
{
  int a = 56;
  auto foo = Foo::createFoo(a);

  foo->study();
}

This obviously doesnot compile as the Foo has no clue what FooImpl is!

Please suggest how can I make this work. The requirement is to keep the main function untouched but have the new functionality.

Please note Yes, I know this could be solved by if statement, but that is not the point. It has a complex implementation in reality I just tried to present it in a fairly understandable problem to study how these templates could work.

EDIT 1
After first editt I seeing the below compliation error abc

CodePudding user response:

As I wrote in the comment: Do not implement createFoo function inside the class declaration.

#include <iostream>

class I_Foo {
public:
  virtual void study(void) = 0;
};

class Foo : public I_Foo {
public:
  // here just DECLARE the method...
  static Foo *createFoo(int x_);
};

/********/
/* SNIP */
/********/

// ...and IMPLEMENT it there
Foo *Foo::createFoo(int x_) {
    if (x_>=50) { 
      return new FooImpl<2>(x_);
    } else {
      return new FooImpl<1>(x_);
    }
}

int main() {
  int a = 56;
  auto foo = Foo::createFoo(a);

  foo->study();
}
  • Related