2016-12-27 7 views
2

私がテンプレートのクラスとしてenum classをテンプレートとして使うクラスがあるとします。ここでは、完全な(ささい)な例です:`enum class`を使った冗長な構文

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; 
} 

は冗長と冗長Animal<AnimalType::Hamster>構文を回避する方法はありますか?

+4

あなたが長いったらしいクラス名の短いエイリアスを定義するには、 'typedef'を使用することができ、それはかなりそれです。 –

答えて

1

彼らは簡単な名前を持つことができます名前空間にクラスとそのenum classを入れて:

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 

すると狭い範囲でusingのステートメントを使用:クラスと名前空間を持っている場合は

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

を同じ名前だと、あいまいなのでusing Animal::Type;と書くことはできません。しかし、あなたは明示的に名前空間について取っている表示するには、グローバルスコープ記号を使用することができます。

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

usingステートメントを追加すると、あまり冗長でなく、元のバージョンで提供されていたシンプルさを失うことになります。 – Drax