Home > Software design >  Abstract class with template function issue
Abstract class with template function issue

Time:05-25

I have an abstract struct I with method a. B and B2 will inherit from it. X struct has an I type member and will instantiate it via createInsance template method based on type. I want to have on B2 an additional function b2Exclusive but I got compilation error that it is not present in A.

error: ‘using element_type = struct B’ {aka ‘struct B’} has no member named ‘b2Exclusive’

Is any way for solving this without defining b2Exclusive for B as well and to keep to structure this way?

#include <iostream>
#include <memory>
using namespace std;

struct I
{
    virtual void a() = 0;
};

struct B : public I 
{   
    B()
    {
        std::cout<<"B\n";
    }
    void a()
    {
        std::cout<<"-a from B\n";
    }
};

struct B2 : public I
{ 
  B2()
  {
    std::cout<<"B2\n";
  }
  void a()
  {
    std::cout<<"-a from B2\n";
  }
  void b2Exclusive()
  {
       std::cout<<"-something for B2\n";
  }
};

using Iptr = std::shared_ptr<I>; 

struct X
{
    void createI()
    {
        if (type == "B")
        {
            createInstance<B>();
        }
        else 
        {
            createInstance<B2>();
        }
        
    }
    
    template <typename T>
    void createInstance()
    {
        auto i = std::make_shared<T>();
        if (type == "B2")
        {
            i->b2Exclusive();
        }
        
    }
    std::string type = "None";
};

int main()
{
    
    X x;
    x.type = "B2";
    x.createI();

    return 0;
}

CodePudding user response:

You can only call b2Exclusive if the template function use typename B2: one way to do so is to create the specialization for that type, such as this for example:

struct X
{
    void createI();
    
    template <typename T>
    void createInstance()
    {
        //do something
        
    }
    
    std::string type = "None";
};

template<>
void X::createInstance<B2> ()
{
    auto i = std::make_shared<B2>();
    i->b2Exclusive();
}

void X::createI()
{
    if (type == "B")
    {
        createInstance<B>();
    }
    else 
    {
        createInstance<B2>();
    }
    
}

int main()
{
    
    X x;
    x.type = "B2";
    x.createI();

    return 0;
}
  • Related