简体   繁体   中英

How to make a raw C++ pointer to point to a template class without specifying the type?

I have seen this in a large codebase, in a header file. When I tried to do it in a source file the compiler complained. The fact that it was OK for the compiler for it being in the header file was still amusing, so I'd like to know how and why it was working. It was a very complex class so I couldn't decipher it.

So here is a simple class:

template <typename T>
class Container {
 public:
  Container(T value) : _value(value){};
  T get() { return _value; }
  void set(T value) { _value = value; }

 private:
  T _value;
};

Now in some other header file, I have this other class:

class ContainerFactory
{
  private:
    Containter<int> *_container1{nullptr}; //this will work as expected
    Container *_container2{nullptr}; //this won't work, the compiler will ask for a type
    std::map<Container*, UIControl*> _map; //this won't work either, but it is handy
    //if I have several types of Container.
}

What so called "tricks" do I have to do in order for _container2 declaration to compiler. I tried a forward declaration and it didn't work obviously. Should I make another class that derives from Container and do some additional stuff? Please advise. Thanks!

A template is a construct which generates C++ entities (classes, functions, and variables at present). But a template by itself is not the thing it generates; it's just a pattern for generating things. It's a fiction that exists at compile time, not a thing that lives in memory somewhere.

So you cannot have a pointer to a template, nor can you have an object of a template.

You can accomplish the broad idea of what you want, an object that could refer to any instantiation of some template. But this would involve creating a type-erased object which provides a specific interface for accessing the type-erased object.

However, type erasure is usually employed when the type you're trying to deal with cannot be named for various reasons or needs to be flexible. If your type is a concrete type, then it must have some idea of what data it stores; if it didn't, it wouldn't be able to use get or set (since those have to return a known type). So either your type needs to be a template (and thus the user defines which Container<T> it works with), or the nature of the type needs to define the Container 's template parameter.

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