Шаблоны Variadic и идеальная пересылка - PullRequest
46 голосов
/ 27 июня 2011

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

По сути, я хочу автоматизировать создание таких функций, как 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 неверен?
Или это просто принципиально невозможно в C ++ 0x?

[править]

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

Ответы [ 3 ]

36 голосов
/ 27 июня 2011

Совершенно верно.Я ожидаю, что это сработает.Так что я думаю, что 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);
}


// [js@HOST2 cpp]$ clang++ -std=c++0x main1.cpp
// [js@HOST2 cpp]$
7 голосов
/ 27 июня 2011

Это, вероятно, причуды 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 голосов
/ 27 июня 2011

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

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

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

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