1
4

2 回答 2

4

Specializing STL types

You are allowed to specialize STL types, but as mentioned in the other answer, they need to be specialized in namespace std. This means you should either do this:

namespace std {
    template <typename _Alloc = std::allocator<Picture>> 
    class list<Picture, _Alloc> { 
        /* stuff */ 
    };
}

Or this:

template<typename _Alloc = std::allocator<Picture>>
class std::list<Picture, _Alloc> {
    /* stuff
};

That being said, Don't inherit from _List_base. That class is an implementation detail of std::list, which means that it's a way one particular implementation of the standard library chose to implement std::list. Other compilers may not have it.

Solving your problem

If you want to have a list-like class that has a .draw() function, you can instead inherit from std::list:

template<class Drawable>
class DrawableList : public std::list<Drawable>
{
   public: 
    // It's handy to have this to refer to the base
    using base_t = std::list<Drawable>; 
    
    using base_t::base_t; // Use std::list`s constructor
    
    // Add your draw function
    void draw(int x, int y) {
        for(Drawable& item : *this) {
            item.draw(x, y); 
        }
    }
};

Caveats of inheriting from std::list

There are some caveats to inheriting from std::list. Because std::list doesn't need dynamic polymorphism, that means that it doesn't have a virtual destructor (or any other virtual methods). You're basically just making a wrapper class around std::list.

In addition, if you add any fields to your DrawableList, those could get cut off when copying it to a std::list. This is known as object slicing.

DrawableList<Picture> a = /* stuff */;

std::list<Picture> b = a; // This will compile without any issues

DrawableList<Picture> c = b; // Oops; any extra fields you had in a got cut off

Alternatively, just use a free draw function:

void draw(std::list<Picture>& pictures, int x, int y) {
    for(auto& picture : pictures) {
        picture.draw(x, y); 
    }
}
于 2019-07-29T20:24:36.360 回答
1

Specialization of STL types is explicitly allowed by standard. However, you need to specialize in the namespace std.

Also, inheriting from _List_base is something which is prohibited by C++ standard. As listed on https://en.cppreference.com/w/cpp/language/identifiers, using reserved identifiers in your program makes your program ill-formed, and all identifiers starting with an underscore followed by capital letter are reserved.

于 2019-07-29T20:14:00.027 回答