1

I've the following code

class Person {
public:
    string fname, lname;
    string getName() {
        return fname + " " + lname;
    }
};
 
template<class T> class A {
    ...
};

int main() {
    A<Person>* a = new A<Person>();
}

Since for template class A, I have T saved as Person. Is there any way I can use the methods and variable in the Person class? Like,

template<class T> class A {
public:
    A() {
        T* person = new T();
        person->fname = "John";
        person->lname = "Doe";
    }
};

Is there some way something like this could be done?

Warren Seine
  • 2,311
  • 2
  • 25
  • 38
  • Are you talking about specializing the definition of `A`? Yes, you can do that. – Nathan Pierson Jun 08 '22 at 03:18
  • 2
    Why are you using `new` everywhere? That seems like a red flag. `new` is rarely required. Just declaring variables of the type directly would have the same effect. Your code in the last example will compile like that. But what do you expect to happen with the `Person` object when the constructor exits? And what is supposed to happen if some other type than `Person` is used for `T`? There is probably a design issue here, but without more detail about what you are trying to do it is hard to make recommendations. – user17732522 Jun 08 '22 at 03:22
  • I'm trying so that in the template class, I can use `T` to make new `Person` classes in the template class. Is that too ambitious? Also, am I using `new` too much? I don't quite see how I can reduce using it. I'm not that adept at C++. – Joseph Park Jun 08 '22 at 03:32
  • 4
    Please learn C++ from good structured material, e.g. one of the [recommended books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). In modern C++ there is almost no practical use of `new` in typical user code. Unfortunately it is often taught in a way that makes it seem like it is something that is supposed to be common in code. It is not though. If you are coming from a different language like Java, then you shouldn't base any assumptions on syntax similarities between the languages. They work completely differently. – user17732522 Jun 08 '22 at 03:40
  • Thanks, I often used C++ to code competitively so I never really learned when to use new. This helped me a lot. – Joseph Park Jun 08 '22 at 03:46
  • It is a well known issue that "competitive programming" uses horrible programming style that would never be accepted as actual production code. It should never be used to properly _learn_ a language. You will only get bad habits like the `new` use above. – user17732522 Jun 08 '22 at 03:49
  • To follow RAII easily, you may want to define a local variable `T person;` instead of using raw pointers + manual allocation. – Louis Go Jun 08 '22 at 03:59
  • Notice that you put implicit constraint on `T`. it should be default constructible and have member `fname`/`lname` than can be assigned from `const char[5]`/`const char[4]` respectively. – Jarod42 Jun 08 '22 at 08:10

2 Answers2

1

Have you tried? I see no problem with this code. Templates are not like Java's generics, you can use the types directly as if it was normal code.

#include <string>
#include <iostream>

class Person{
public:
    std::string fname, lname;
    std::string getName(){
        return fname + " " + lname;
    }
};

template<class T> class A{
public:
    A(){
        T person = T();
        person.fname = "John";
        person.lname = "Doe";
        std::cout << person.fname << " " << person.lname << "\n";
    }
};

int main(){
    A<Person> a = A<Person>();
}

Output:

John Doe

Live example

Remind yourself though that the template must be implemented in the header files. The compiler has to have access to implementation to instantiate the templates.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • Thank you for that code. I kept trying to do something stupid like ` `Person p = Person();` `return (T)p;` I kept getting Link errors and stuff. Seeing your code really helped. – Joseph Park Jun 08 '22 at 03:44
  • 1
    @JosephPark If you are getting linker errors with template, [Why can templates only be implemented in the header file](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) might be of interest to you. – Quimby Jun 08 '22 at 05:06
  • 2
    Why `T person = T()` instead of just `T person`? – Elliott Jun 08 '22 at 05:59
  • @Elliott I just removed the pointers. Kept the syntax as close as OP's code as possible to avoid confusion. – Guillaume Racicot Jun 08 '22 at 13:08
0

While you can do that, you may want to limit the possible types to subtypes of Person:

#include <concepts>
#include <string>

struct Person {
    std::string first_name;
    std::string last_name;
};

struct Employee : Person {
    std::string position = "Manager";
};

template <std::derived_from<Person> P>
struct A {
    P p;

    A() {
        p.first_name = "John";
        p.last_name = "Smith";
    }
};

int main() {
    A<Person> ap; // works
    A<Employee> ae; // works
}

See online

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93