Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Template class implementation has compilation issues

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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();
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading