Очень часто можно параметризовать фабричный метод, скажем, фабрику Object
с именем Object::create()
, над тегом , например, над параметром нетипичного шаблона, таким как enum, скажем, ObjectTag
. Шаблон функции Object::create()
, параметризованный по ObjectTag
, предоставляет фабричный метод publi c, который специализируется для каждого указанного перечислителя c перечисления ObjectTag
и который в свою очередь использует, например, частный конструктор Object
, который не публикуется в его публичном c API.
#include <iostream>
enum class ObjectTag
{
kFirst,
kSecond,
kThird
};
struct Object {
template <ObjectTag TAG>
static Object create() = delete;
void foo() const { std::cout << foo_ << "\n"; }
private:
explicit Object(const int foo) : foo_(foo) {}
int foo_;
};
template<>
Object Object::create<ObjectTag::kFirst>() { return Object(11); }
template<>
Object Object::create<ObjectTag::kSecond>() { return Object(22); }
template<>
Object Object::create<ObjectTag::kThird>() { return Object(33); }
int main() {
const auto a = Object::create<ObjectTag::kFirst>();
const auto b = Object::create<ObjectTag::kSecond>();
const auto c = Object::create<ObjectTag::kThird>();
a.foo(); // 11
b.foo(); // 22
c.foo(); // 33
}
Обратите внимание, что основной шаблон шаблона функции-члена Object::create()
был удален, так что существуют определения только (полных) явных специализаций об этом.