简体   繁体   中英

can I pass an object to a class via template c++

Can I do this:

class A
{
    public:
    void print()
    {
         std::cout<<"A"<<std::endl;
    }
};

class B
{
    public:
    void print()
    {
         std::cout<<"B"<<std::endl;
    }
};

template <class T>
class C 
{
     public:
     void say()
     {
          T.print();
     }
};

int main()
{
     A a;
     B b;
     C<a> c;
     c.say();
     C<b> d;
     d.say();

     return 0;
 }

If I don't want to use a base class for A and B , what is the best way (fast running speed) way of doing this?

There are multiple things wrong with your code.

You seem to be mixing up types with instances (or classes and objects).

This code should actually compile and work as intended.

#include <iostream>

class A
{
    public:
    void print()
    {
         std::cout<<"A"<<std::endl;
     }
};

class B
{
    public:
    void print()
    {
         std::cout<<"B"<<std::endl;
     }
};

template <class T>
class C 
{
     public:
     void say(T obj)
     {
          obj.print();
          // If T::print() were static, you could call it like that instead.
     }
};

int main()
{
     A a;
     B b;
     C<A> c; // template for C demands a class, not an object!
             // in practice this would mean you write 'A' instead of 'a' here
     c.say(a);
     C<B> d; // same here
     d.say(b);
}

Where T is a type T.print(); is not valid C++. Instead you have the following options:

If you make print a static method you could do:

void say()
{
     T::print();
}

This might be a good route if the print method does not need any state. It's nothing more that than a straight (possibly inlined) function call. So not much scope for performance problems.

Otherwise you have to pass the object :

void say(T object)
{
    object.print();
}

There are some options for how you would pass the object. Whether by value as above (assuming T isn't a reference/pointer type) or by reference. These may or may not have significance on the performance depending on the particular case.

Or create an instance within the say method:

void say()
{
    T().print();
}

For simple cases this is likely to optimise out to be essentially the same as the static print method case. Though of course the constructing a T could be potentially costly for less trivial cases.

At first you forgot the semicolons behind the class declarations and somehow your main does not return an integer. So assuming thats fixed there is only a small amount of code there, which is still wrong, but is a huge impact. You mixed up run time and compile time.

 A a;
 B b;
 C<a> c;
 C<b> d;

You try to use a non-const instance as a template parameter, which makes no sense. It will be created on runtime, but on compiletime you have no clue about those. A template parameter does not take a non-const value, most of time it simply takes a type , like in your code. template<class T> or template<typename T> is expecting some type, not an instance of something. However you can recieve instances by doing things like template<A myConstA> . Anyways you need to rewrite it, such that it recieves the type , as it is known at compile-time.

A a;
B b;

//you can do C<decltype(a)>, too
C<A> c;
C<B> d;

You have your print function like this:

void print()
{ T.print(); }

But you cannot call a non-static function without an instance! Thus you have a few possibilities to fix this. Either take a reference of type T and call from that, like so:

void print(T& t)
{ t.print(); }

or simply, if ok, do this:

void print()
{ T().print(); }

or make the print functions of both A and B static! Try it online !


By the way whatever you do, if you decide not to make it static, make it a const function and noexcept , since it never throws and does change nothing from the instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM