Подтвердить что ты не робот

Шаблоны шаблонов Variadic и совершенная пересылка

Этот вопрос в шаблон генератора объектов заставлял меня думать о путях автоматизировать его.

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

make<std::pair>(1, 2);         // equivalent to std::make_pair(1, 2)
make<std::binder2nd>(&foo, 3); // equivalent to std::bind2nd(&foo, 3);

Можно ли записать эту функцию make? Я пробовал это, но он не работает в GCC 4.5 или 4.6:

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
    return TemplateClass<Args...>(std::forward<Args>(args)...);
}

Если я попытаюсь позвонить (например) make<std::pair>(1, 2), я просто получаю

error: no matching function for call to 'make(int, int)'

Я получил синтаксис в любом месте здесь? Или это право, и GCC ошибается?
Или это просто принципиально невозможно в С++ 0x?

[править]

Предложение N2555 кажется, что это разрешено и GCC утверждает, что реализовала его в GCC4.4.

4b9b3361

Ответ 1

Это точно. Я ожидаю, что это сработает. Поэтому я считаю, что GCC ошибается, отвергая это. FWIW:

#include <utility>

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
    return TemplateClass<Args...>(std::forward<Args>(args)...);
}

int main() {
  make<std::pair>(1, 2);
}


// [[email protected] cpp]$ clang++ -std=c++0x main1.cpp
// [[email protected] cpp]$

Ответ 2

Это, вероятно, причуда GCC. Я могу получить следующее для работы с моментальным снимком dev (у меня сейчас нет копии 4.6):

template<
    template<typename...> class TemplateClass
    , typename... Args

    , typename Result = TemplateClass<Args...>
    // Also works with the arguably more correct
    // , typename Result = TemplateClass<
    //     typename std::decay<Args>::type...
    // >
>
Result
make(Args&&... args)
{ /* as before */ }

Ответ 3

Это совершенно неправильно - возьмите make_shared, например. Точка make_shared заключается в том, что для ее использования требуется экономия времени выполнения. Но что произойдет, если я попытаюсь использовать make<std::shared_ptr>? Не думайте, что это сработает. Или как насчет типов, где только некоторые аргументы конструктора являются аргументами шаблона, а остальные - нет? Например, make<std::vector, int>(other_vector.begin(), other_vector.end()); - типы итераторов не участвуют, но вы все равно передаете их.

Невозможно написать общую make функцию.

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