namespaced class template inheritance in C++

亡梦爱人 提交于 2019-12-13 05:14:49

问题


In an earlier question, I asked asked class template inheritance in C++.

I now have an extra level to add!

Consider the following code. (Assume the member definitions are present and accurate)

namespace Game
{
    namespace Object
    {
        template<typename T>
        class Packable
        {
        public:

            /**
             * Packs a <class T> into a Packet (Packet << T)
             * Required for chaining packet packing
             *************************************************/
            virtual sf::Packet& operator <<(sf::Packet& packet) = 0; // Work-horse, must be defined by child-class
            friend sf::Packet& operator <<(sf::Packet& packet, T &t);
            friend sf::Packet& operator <<(sf::Packet& packet, T *t);

            /**
             * Unpacks a <class T> from a Packet (Packet >> T)
             * Required for chaining packet unpacking
             *************************************************/
            virtual sf::Packet& operator >>(sf::Packet& packet) = 0; // Work-horse, must be defined by child-class
            friend sf::Packet& operator >>(sf::Packet& packet, T &t);
            friend sf::Packet& operator >>(sf::Packet& packet, T *t);

            /**
             * Unpacks a <class T> from a Packet (T <<= Packet)
             * Returns the <class T> for convienence
             *************************************************/
            //friend T& operator <<=(T t, sf::Packet& packet); // Returning reference to cut down on copying (they're already passing us our own copy)
            friend T& operator <<=(T &t, sf::Packet& packet);
            friend T* operator <<=(T *t, sf::Packet& packet);
        };
    }
}

And this Ship class inherits from Game::Object::Packable

class Ship : public Game::Object::Base<Ship>, public Game::Object::Packable<Ship>
{
    public:
        Ship( void );
        //...

        // For packing and unpackinng packets
        sf::Packet& operator <<(sf::Packet& packet);
        sf::Packet& operator >>(sf::Packet& packet);
}

What we're left with is the following error.

(null): "Game::Object::operator<<(sf::Packet&, Ship*)", referenced from:

I've come to the conclusion that it must have something to do with the use of namespaces. What is the solution to this if I wanted to retain the namespaces?

Here is an excerpt of the method definitions. Do I have to dereference the namespace? (I don't think that even means anything haha)

/**
 * Packs a <class T> into a Packet (Packet << T)
 * Required for chaining packet packing
 *************************************************/
template<class T>
sf::Packet& operator <<(sf::Packet& packet, T *t)
{
    // Call the actual one, but basically do nothing... this needs to be overrided
    return packet << *t;
}

template<class T>
sf::Packet& operator <<(sf::Packet& packet, T &t)
{
    // Call the pointer one, but basically do nothing... this needs to be overrided
    return packet << &t;
}

// ... other definitions etc.

回答1:


The friend declaration (non-template non-member) does not match the befriended function templates. I would advice you to provide the implementation inside the class definition:

    template<typename T>
    class Packable
        friend sf::Packet& operator <<(sf::Packet& packet, T &t) {
           return packet << t;
        }
    //...

This allows for a free non-template function that will be generated by the compiler on demand. Other alternatives include befriending the template or the template specialization that you care about.

Of course, you can ignore friendship completely and just provide the templates at namespace level, since they are implemented in terms of a public function…


Related:

  • https://stackoverflow.com/a/23718008/36565
  • https://stackoverflow.com/a/4661372/36565


来源:https://stackoverflow.com/questions/23729016/namespaced-class-template-inheritance-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!