0

I am trying to pass a pointer to a templated object to another class.

template <int size>
class A {
public:
    int a[size] = {0};

    int getA(int n) {
       return a[n];
    }
};


class B {
public:
    A<>* b;

    void setB(A<>* n) {
        b = n;
    }
};


int main()
{
    const int size1 = 10;

    A<size1> data1;
    B b1;
    
    b1.setB(&data1);
}

Which doesn't work.

As a solution, I can create the B class as a template class and create B object as B<A<size1>> b1; but this will create multiple objects if I multiply A<sizeX>, which I don't want since this code is for an embedded project which has finite resources.

All I want is to pass the pointer of data1 object to another class function and store it inside. The code I'm looking for is for C++03, I cannot use C++11 features such as shared pointers.

Is there a way to do this?

Appreciate any help,

8
  • And there's no reasonable way to make class B a template as well? Commented Mar 3, 2022 at 17:27
  • Can you use std::any b;? Commented Mar 3, 2022 at 17:29
  • What about a base class for A<N> types? What about registering pointers to base type? Commented Mar 3, 2022 at 17:32
  • Depending on what exactly you are doing, you could have A inherit from a base class, and then in B you store a pointer to that base class. Commented Mar 3, 2022 at 17:32
  • 1
    @MeCe That is a difficult problem to solve. Mixing run-time and compile-time constructs is not very easy. Commented Mar 3, 2022 at 17:47

2 Answers 2

1

You have gotten yourself into a bit of a catch-22 situation.

You can't hold a templated A inside of B without making B templated as well, eg:

template <int size>
class A {
public:
    int a[size];

    int getA(int n) {
       return a[n];
    }
};

template <int size>
class B {
public:
    A<size>* b;

    int getA(int n) {
        return b->getA(n);
    }

    void setB(A<size>* n) {
        b = n;
    }
};

int main()
{
    const int size1 = 10;

    A<size1> data1;
    B<size1> b1;
    
    b1.setB(&data1);
    int a = b1.getA(0);
}

Or by giving A a non-templated base class for B to hold, eg:

class A_base
{
    virtual ~A_base() {}
    virtual int getA(int n) = 0;
};

template <int size>
class A : public A_base {
public:
    int a[size];

    int getA(int n) {
       return a[n];
    }
};

class B {
public:
    A_base* b;

    int getA(int n) {
       return b->getA(n);
    }

    void setB(A_base* n) {
        b = n;
    }
};

int main()
{
    const int size1 = 10;

    A<size1> data1;
    B b1;
    
    b1.setB(&data1);
    int a = b1.getA(0);
}

Otherwise, you will have to make B just hold a void* pointer, and then require the caller to extract that void* and decide what to cast it to, eg:

template <int size>
class A {
public:
    int a[size];

    int getA(int n) {
       return a[n];
    }
};

class B {
public:
    void* b;

    void* getB() {
        return b;
    }

    void setB(void* n) {
        b = n;
    }
};

int main()
{
    const int size1 = 10;

    A<size1> data1;
    B b1;
    
    b1.setB(&data1);
    int a = static_cast< A<size1>* >(b1.getB())->getA(0);
}
Sign up to request clarification or add additional context in comments.

Comments

1

I think you will want to pass the size from a constructor. Templates don't fit for this use case.

1 Comment

Thanks for the answer. However I cannot pass size from the constructor since I don't want dynamic memory allocation on an embedded system.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.