Лучшая альтернатива typedef для шаблона функции? - PullRequest
17 голосов
/ 17 декабря 2011

Я хотел бы сделать что-то вроде этого:

template <class DataType>
DataType myFunc(DataType in)
{
   ...
}

typedef myFunc<int> myFunc_i;

myFunc_i(37);

... однако, typedefs нельзя использовать для таких функций в C ++. Что мне было интересно, так это то, какие предпочтения ... Единственные, о которых я могу думать:

1) Просто разберитесь с этим и всегда используйте синтаксис myFunc 2) Вручную создайте функцию-обертку, например

inline int myFunc_i(int in)
{
    return myFunc<int>(in);
}

Это будет работать, но будет иметь недостатки, требующие дополнительного обслуживания, и вероятность того, что он выйдет из синхронизации (т. Е. Если вы измените сигнатуру функции для myFunc).

Мысли

Ответы [ 5 ]

14 голосов
/ 17 декабря 2011

Попробуйте:

typedef int (*myFunc_i_type)(int);
myFunc_i_type const myFunc_i = &myFunc<int>;

Это вызовет ошибку компилятора, если сигнатура myFunc когда-либо изменится.Делая это const также запрещает переназначение.Указатели на функции также можно вызывать как любую обычную функцию: myFunc_i(5).

Если вы не хотите ошибки компилятора, а хотите, чтобы она сама обновлялась, используйте auto (снова с const):

auto const myFunc_i = &myFunc<int>;
7 голосов
/ 17 декабря 2011

Кто-то может не согласиться, кто-то может дергать коленями против этого, но рассмотрите этот вариант:

#define myFunc_i myFunc<int>

Что касается макросов, то этот вариант вполне безопасен;единственная опасность состоит в том, что кто-то может переопределить или отменить его позже.

Помимо этого, он обладает всеми преимуществами auto const myFunc = myFunc<int>;.Если вы хотите auto, но пока не хотите использовать функции C ++ 0x, это более переносимый способ достижения того же эффекта.

5 голосов
/ 17 декабря 2011

Пример кода:

#include <iostream>


template <typename T>
T sqr(T a){
    return a*a;
}

auto s = sqr<int>;
int main() {

    std::cout<<s(3.9);
    return 0;
}

печатает 9, это означает, что используется функция int
auto требует c ++ 0x, вместо этого вы можете использовать реальное имя типа, но это ужасно, и вам также нужно проверить изменение подписи. Кроме того, этот код может запретить вашему компилятору встроить эту функцию

  • Что касается меня, часто лучше использовать полное имя с <>

  • В вашем случае вам не нужно использовать <>, поскольку достаточно myFunc (DataType может быть получено из типа аргумента)

2 голосов
/ 18 июля 2017

Использование decltype:

template <class DataType>
DataType myFunc(DataType in)
{
   ...
}

using myFunc_i = decltype(myFunc<int>(0));

myFunc_i(37);
2 голосов
/ 25 апреля 2016

Я бы немного улучшил ответ Xeo.

Вместо использования:

auto const myFunc_i = &myFunc<int>;

Я бы использовал

constexpr auto myFunc_i = &myFunc<int>;
...