0

I have a Controller class which is designed to be inherited. It currently has a name() pure virtual method, like this:

class Controller {
public:
    virtual const std::string name() const = 0;
}

The name is really a class-property, rather than an instance property. It shouldn't change between instances of a subclass, so really, virtual isn't the best thing to do here. Anyway, I've now hit a problem where I need the name at compile-time, in a template function. Obviously T::name() doesn't work, and because the subclasses won't be default constructible, I can't even hack around it with T()::name().

So something needs to change, but I can't figure out the best way to do this. I need to be able to access name in the following situations:

  • At compile-time, when I have a subclass type (e.g. T::name())
  • At runtime, when I have an instance of a subclass (e.g. instance->name())
  • At runtime, when I have a Controller* (e.g. pointer to the base class)

name() doesn't have to be method, it can be a public attribute, or something else. But no-matter what I try I can only seem to satisfy 2 of the above 3 requirements.

Can anyone suggest any good approaches for solving this?

Jonas
  • 6,915
  • 8
  • 35
  • 53
Kazade
  • 1,297
  • 2
  • 15
  • 25
  • 2
    What do you mean with "at compile time"? What kind of statement do you need to run at compile time with a string? – The Quantum Physicist Aug 09 '17 at 08:57
  • Hint: [not possible](https://stackoverflow.com/questions/27123306/is-it-possible-to-use-stdstring-in-a-constexpr) – Bartek Banachewicz Aug 09 '17 at 09:00
  • In a template function, I need to get the name of the passed in type. e.g. `template bool has_controller() const { ... need T::name() here ... }` – Kazade Aug 09 '17 at 09:03
  • 1
    @Kazade You want to check if its base class is controller? Or whether it's a specific type? Have you heard of C++11 [type traits](http://en.cppreference.com/w/cpp/types)? – The Quantum Physicist Aug 09 '17 at 09:05

1 Answers1

1

Unfortunately, you cannot declare a static method virtual so something like this wouldn't work :

struct BaseClass {
  static virtual std::string name() =0;
};

struct ChildClass  {
  static std::string name() {
    return "my_name";
  }
};

you can instead make a method with a slightly different name :

struct BaseClass {
  virtual std::string name() =0;
};

struct ChildClass  {
  std::string name() {
    return ChildClass::_name(); 
  };

  static std::string _name() {
    return "my_name";
  }
};

which will work with the three cases you describe :

ChildClass c;
BaseClass& b = c;
std::cout << ChildClass::_name() << std::endl;
std::cout << c.name() << std::endl;
std::cout << b.name() << std::endl;
Serge Kireev
  • 176
  • 1
  • 8