2012-02-24 3 views
10

Давайте asssume, что у нас есть шаблон несильно:Можно ли передать шаблон функции в качестве аргумента шаблона?

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... 
} 

Возможно ли это?

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

EDIT:

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

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... 
} 

ответ

8

Нет, это невозможно. От 14.3.3 в N3337:

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

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

+1

Я не понимаю ни слова о том, что вы говорите. -1, можете ли вы предоставить иллюстрацию для нас, которые не владеют стандартным? – lurscher

+0

@ lurscher, потому что вы не понимаете, что это ужасная причина для downvote. Я не сжимаю квантовых физиков, когда они говорят о квантовой физике, потому что я этого не понимаю. –

+0

@SethCarnegie, я не согласен. Я думаю, что это само по себе очень хорошая причина. кроме того, ответ неверен; то, что вопрос хочет сделать, вполне возможно, даже в C++ 03.Я думаю, что есть разрыв между тем, что спрашивает SO, и что отвечает pmr, следовательно, downvote. Если он улучшит свой ответ, я буду более чем счастлив снять его – lurscher

1

Шаблоны в 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

. Я действительно не вижу разницы между этим кодом и кодом «частичного решения». Дело в том, что в этом подходе невозможно использовать 'some_function' с различными типами без явного добавления нового аргумента шаблона. И мне любопытно, есть ли более гибкий (но все же без использования класса). –

0

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

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

+0

Я знаю, что могу использовать класс. Я написал это в своем посте. Вопрос об общих функциях. Но в соответствии с тем, что написал @pmr, это кажется синтаксически невозможным. –

+1

Синтаксис использования функции OP (и расширения) недействителен. Правильным является 'template class someTemplate'. Здесь также ничего не говорится о 'оценке'. Представьте это так: аргумент шаблона шаблона может быть сопоставлен только с именем шаблона класса с тем же списком параметров шаблона (это важно для аргументов шаблона непигового типа). Это имя шаблона затем вводится в другой шаблон и может быть введено там. Проблема заключается в «шаблоне класса». Я не вижу конкретных причин для этого ограничения, но я не нахожусь в комитете и нет адвоката языка. – pmr

+0

@pmr Uhm. Что ж. Синтаксис, который я использовал в примере, был частично псевдокодом, то есть я знал, что не могу использовать ключевое слово 'class', поэтому я не использовал его. Речь шла об этой идее. –

Смежные вопросы