Могу ли я использовать decltype(), чтобы избежать дублирования кода при явном создании экземпляров шаблона?

У меня есть длинное объявление функции шаблона:

template <typename T> void foo(lots ofargs, goin here, andeven more, ofthese arguments, they just, dont stop);

без перегрузок. и я хочу явно создать его экземпляр. Я могу написать (скажем, для T = int):

template void foo<int>(lots ofargs, goin here, andeven more, ofthese arguments, they just, dont stop);

Но я действительно не хочу копировать это длинное объявление. Я бы хотел сказать что-то вроде:

template <typename T> using bar = decltype(foo<T>);

а потом:

template bar<int>;

Теперь первая строка компилируется (GCC 4.9.3), а вторая нет. Могу ли я заставить его работать как-то? Или я могу использовать decltype() какой-то другой способ избежать копирования объявления для создания экземпляра?

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


person einpoklum    schedule 11.04.2016    source источник


Ответы (1)


Конечно. Из [temp.explicit]:

Синтаксис явного создания экземпляра:
явное создание экземпляра:
externopt template объявление

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

Нам нужна декларация. Давайте представим, что мы начинаем с:

template <class T> void foo(T ) { }

Мы можем явно специализироваться через:

template void foo<char>(char );   // template-id
template void foo(int );          // or just template-name, if the types can be deduced

Это то же самое, что написать:

using Fc = void(char );
using Fi = void(int );

template Fc foo<char>;
template Fi foo;

Это то же самое, что написать:

template <class T> using F = decltype(foo<T> );

template F<char> foo<char>;
template F<int> foo;

По сути, причина, по которой template bar<int> не работает, заключается в том, что это не объявление. Тебе тоже нужно имя.

person Barry    schedule 11.04.2016
comment
Я редактирую вопрос, чтобы убедиться, что вы не можете вывести аргумент шаблона для аргументов функции, что меня действительно интересовало. Я просто добавил T t для хорошей меры, не хотел, чтобы вы используйте его ... Если ваш ответ все еще актуален, то отлично. - person einpoklum; 12.04.2016
comment
@einpoklum Это далеко не ясно из вопроса, и почему вы думаете, что мой ответ не имеет значения? - person Barry; 12.04.2016
comment
Я не говорил, что это не имеет значения, у меня просто возникло ощущение (до вашего последнего редактирования), что вы, возможно, полагаетесь на это больше, чем на самом деле. - person einpoklum; 12.04.2016