Можно ли передать шаблон функции в качестве аргумента шаблона? - PullRequest
10 голосов
/ 24 февраля 2012

Предположим, что у нас есть функция шаблона:

template<typename T1, typename T2, typename T3>
T3 such_fun(T1 a, T2 b) {
    // do something...
}

, и теперь мы хотим использовать ее в качестве аргумента в другом шаблоне, например, вот так

template<typename T1, template<typename, typename, typename> some_function>
void big_fun(T1 a) {
   // some code...
   a = some_function<T1, T1, T1>(a, a);
   // some code...
}

Этовозможно?

Я знаю, что могу использовать структуру с оператором define ().Мне просто интересно узнать о функциях.

РЕДАКТИРОВАТЬ:

Пока я писал этот вопрос, мой друг нашел частичное решение:

template<typename T1, T1 (*some_function)(T1, T1)>
void big_fun(T1 a) {
   // some code...
   a = some_function(a, a);
   // some code...
}

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

template<typename T1, typename T2, template<typename, typename, typename> some_function>
void big_fun(T1 a, T2 b) {
   // some code...
   a = some_function<T1, T1, T1>(a, a);
   a = some_function<T1, T2, T1>(a, b);
   b = some_function<T2, T2, T2>(b, b);
   b = some_function<T2, T1, T2>(b, a);
   // some code...
}

Ответы [ 3 ]

8 голосов
/ 24 февраля 2012

Нет, это невозможно.Начиная с 14.3.3 в N3337:

Аргумент шаблона для параметра шаблона шаблона должен быть именем шаблона класса или шаблона псевдонима, выраженным в виде выражения id.Когда аргумент шаблона именует шаблон класса, при сопоставлении аргумента шаблона шаблона с соответствующим параметром учитываются только шаблоны первичного класса;частичные специализации не рассматриваются, даже если их списки параметров совпадают со списком параметров шаблона шаблона.

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

1 голос
/ 24 февраля 2012

Шаблоны в C ++ компилируются во время компиляции с использованием конкретных типов.Они должны быть известны.

Это говорит о том, что вы можете пойти немного дальше с частичным решением, передав шаблон функции, аргументы которого могут быть выведены.Обратите внимание, что это ничем не отличается от явной передачи функции с конкретными типами, которые вы просто должны набирать меньше.

template<typename T>
T square(T a, T b)
{
    return a * b;
}

template<typename T, T (*some_function)(T, T)>
T test(T a) 
{
   return square (a, a);
}

void main()
{
    int a = test<int, square>(2);
    float b = test<float, square>(2.2f);
}
0 голосов
/ 24 февраля 2012

Пока template< typename T1, typename T2, typename T3> someTemplate оценивает некоторый фактический класс без ошибок, вы можете использовать его с любым количеством комбинаций, как вы хотите, вне и внутри других шаблонов.

Вы пытались его скомпилировать?Покажите нам, какую ошибку вы получаете (и конкретный образец)

...