Конструктор класса с типом шаблона без аргументов - PullRequest
2 голосов
/ 19 сентября 2009

Для нормальной функции C ++ возможно, чтобы параметры шаблона не появлялись в списке аргументов:

template<typename T>
T default_construct()
{
    return T();
}

и назовите это с

some_type x = default_construct<some_type>();

Хотя тип, который я использую, отсутствует в списке аргументов, я все равно могу передать его функции. Теперь я хочу сделать это в конструкторе класса:

struct Base;

template<typename T>
Base* allocate()
{
    return new T; //Assume T derives from Base...
}

struct factory {
    template<typename T>
    factory()
        : func(allocate<T>)
    {}

    std::tr1::function<Base*()> func;
};

но я не могу найти способ передать параметр конструктору, когда я хочу создать экземпляр factory.

Есть ли способ сделать это без превращения класса в шаблонный класс или отправки неиспользуемого T объекта в конструктор?

Ответы [ 3 ]

9 голосов
/ 19 сентября 2009

Нет, нет способа сделать это. Примечание в 14.8.1/5 в Стандарте объясняет, почему

[Примечание: поскольку явный список аргументов шаблона следует за именем шаблона функции, а также потому, что шаблоны функций-членов преобразования и шаблоны функций-членов-конструкторов вызываются без использования имени функции, невозможно предоставить явный список аргументов шаблона для этих функций. шаблоны функций. ]

Конечно, это не обязательно должен быть T объект, который вы отправляете. Это может быть любой объект, который имеет T в своем типе

template<typename T> struct type2type { };

struct factory {
    template<typename T>
    factory(type2type<T>)
        : func(allocate<T>)
    {}

    std::tr1::function<Base*()> func;
};

factory f((type2type<Foo>()));
3 голосов
/ 19 сентября 2009

Нет, вы не можете. Использование неиспользуемого объекта данного типа вызывается с использованием «объекта тега типа». Вы можете создавать глобальные переменные каждого типа или использовать конструктор по умолчанию каждый раз.

Вы можете разумно надеяться, что если конструктор будет встроенным, тег типа никогда не будет создан.

0 голосов
/ 19 сентября 2009

Ответы Литба и Вранг-Вранга хорошие. В качестве еще одной возможности вы можете рассмотреть объявление всех ваших (не копируемых) конструкторов частными или защищенными и создание одного или нескольких статических шаблонов функций-членов factory create<T>(). Затем, чтобы определить экземпляр фабрики, вместо

factory<SomeType> f;                      // 1 (doesn't compile)

Вы бы написали

factory f(factory::create<SomeType>());   // 2

Очевидно, что не так красиво, как (1), но ИМХО немного понятнее, чем использование тегов типа. (Компилятор устранит копию на практике.)

Кстати, есть ли причина, по которой вы не можете просто сделать factory шаблоном класса? Тогда синтаксис из (1) будет компилироваться. (Однако это будет означать, что фабрики разных типов не могут быть отнесены друг к другу.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...