0

I have a class exactly as below.

But I get errors when declaring pointer var to my class. What's happening here? There are some similar questions here but I couldn't understand why my case is not working as the pointer is of the class itself.

Edit: going by aweebit's answer.

suppose now if I have an overloaded "foo" for printing any integer which is passed. is there some way i can use the same objA? or will i have to create another objAA with template argument int? i will edit my question to reflect this.

do i really have to make a separate object for every data-type? or is there some way i can achieve late binding at runtime?

code:

#include<iostream>

template <class T>
class A;

int main ()
{
    A* objA = NULL;
    objA = new A();
    
    objA->foo("some string");
    objA->foo(1);

    delete objA;
    objA = NULL;
    
    return 0;
}

template <class T>
class A
{
    void foo(T);
};

template <class T>
void A<T>::foo(T str)
{
    std::cout << str << "\n";
}

template <class T>
void A<T>::foo(T inte)
{
    std::cout << inte << "\n";
}

1 Answers1

0

Since A is a class template (and since the template argument cannot be deduced – only relevant since C++17), you have to explicitly specify the template argument:

A<const char*>* objA = NULL;
objA = new A<const char*>();

Or with std::string:

A<std::string>* objA = NULL;
objA = new A<std::string>();

Another thing you will have to do is to move the class definition to the top of your file. This has to do with the fact that at the moment you create a variable of any type, the entire definition of that type must be available (this applies to normal classes, too).

And the last problem your code has is that you are trying to call A::foo() although it is a private method since class members are private by default.

Addressing your question in the comments:

Once you instantiate the class template, the type parameter T is replaced with the corresponding argument (const char* or std::string in our case), and since C++ is a strongly typed language, you will not be able to pass an argument of a different type to A::foo() (unless it can be implicitly converted, but that is another story).

Since your class does not have any data, and so the A::foo() method does not use any member variables, you could take the risk and cast the pointer to a pointer to a different instantiation of the class template using C-style cast or the C++ specific reinterpret_cast, like so:

((A<int>*) objA)->foo(1);
reinterpret_cast<A<int>*>(objA)->foo(1);

But do not take it as a general advice. You really have to know what you are doing if you use something like that!

A better solution would be to use a function template, since A::foo() only really depends on its argument's type. So you could get rid of the A class altogether and make foo a standalone function template, or, if you really want to keep the class (maybe you want to store some data in it?), you should consider making foo a member function template:

#include <iostream>

template <class T>
class A
{
private:
    T data;
public:
    template <class U>
    void foo(U);
};

int main ()
{
    A<const char*>* objA = NULL;
    objA = new A<const char*>();

    objA->foo("some string");
    objA->foo(1);

    delete objA;
    objA = NULL;

    return 0;
}

template <class T>
template <class U>
void A<T>::foo(U value)
{
    std::cout << value << "\n";
}
aweebit
  • 527
  • 3
  • 11
  • okay, now if I have an overloaded "foo" for printing any integer which is passed. is there some way i can use the same objA? or will i have to create another objAA with template argument int? i will edit my question to reflect this. – Mehar Charan Sahai Aug 12 '21 at 05:20
  • I have updated my answer with a couple of details that were missing and an answer to your new question. Please take a look at it. – aweebit Aug 12 '21 at 09:59