Jack Deeth
Jack Deeth

Reputation: 3357

Redundant syntax with `enum class`

Suppose I have a templated class, where I use an enum class as a template parameter. Here's a full (trivial) example:

enum class AnimalType { Dog, Cat, Hamster };

template <AnimalType>
class Animal {
public:
  std::string speak();
};

template <>
std::string Animal<AnimalType::Dog>::speak() {
  return "Woof";
}

template <>
std::string Animal<AnimalType::Cat>::speak() {
  return "Meow";
}

template <>
std::string Animal<AnimalType::Hamster>::speak() {
  return "Iä! Iä! Cthulhu fhtagn!";
}

int main() {
  Animal<AnimalType::Dog> dog;
  Animal<AnimalType::Cat> cat;
  Animal<AnimalType::Hamster> hamster;

  cout << dog.speak() << endl << cat.speak() << endl << hamster.speak() << endl;
}

Is there a way of avoiding the verbose and redundant Animal<AnimalType::Hamster> syntax?

Upvotes: 2

Views: 75

Answers (1)

Jack Deeth
Jack Deeth

Reputation: 3357

Put the class and its enum class into a namespace where they can have brief names:

namespace Animal {

enum class Type { Dog, Cat, Hamster };

template <Type>
class Animal {
public:
  std::string speak();
};

template <>
std::string Animal<Type::Dog>::speak() {
  return "Woof";
}

… etc

} // namespace Animal

Then in a narrower scope use a using statement:

int main(){
  using Animal::Animal;
  using Animal::Type; // error
  Animal<Type::Dog> dog;
  Animal<Type::Cat> cat;
  … etc
}

If the class and namespace have the same name, you can't write using Animal::Type; because it's ambiguous. But you can use the global scope symbol to explicitly show you're taking about the namespace:

int main(){
  using ::Animal::Animal;
  using ::Animal::Type; // ok
  Animal<Type::Dog> dog; 
  … etc
}

Upvotes: 1

Related Questions