Специализированный шаблон для подписи функции

В этом тестовом коде:

#include <string>
#include <iostream>

using namespace std;

template <typename T> class Signal;

template <typename T, typename U>
class Signal<T (U)>
{
public:
Signal<T (U)>(T (*ptr)(U))
{
}
};

void Print(string const& str)
{
cout << str << endl;
}

int main(int argc, char *argv[])
{
Signal<void (string const&)> sig = &Print;
return 0;
}

Почему я должен написать template <typename T> class Signal;?

Почему я должен это указать?

4

Решение

Вы создаете специализацию Signal который объединяет произвольные типы T а также U в форму T(U), Это составлено как специализация Signal<T(U)>: в параметре указан только один тип, поэтому мы объявили Signal принимая только один тип T, Это было бы невозможно без этой декларации.

Вот простой пример:

template <typename T> struct A;

template <typename T, typename U> struct A<T(U)> {

};

int main() {

A<void(int)> a;

}

Типы void а также int связаны с типами T а также U соответственно. Это объединено в тип void(int) используется в первичной декларации A специализировать класс.

2

Другие решения

Ты не иметь делать то, что вы делаете, но это самый гибкий подход. Однопараметрический шаблон со специализацией выглядит так:

  • Шаблон параметризованный по одному типу …

    template <typename> struct Foo;
    
  • … но это определено только для типов функций:

    template <typename R>
    struct Foo<R()> { /* ... */ };
    
    template <typename R, typename A1>
    struct Foo<R(A1)> { /* ... */ };
    
    template <typename R, typename ...Args>
    struct Foo<R(Args...)> { /* ... */ };
    

Альтернативой было бы жестко закодировать сигнатуру функции:

  • Шаблон класса, в котором хранится указатель на функцию с одним аргументом:

    template <typename R, typename A>
    struct Bar
    {
    R (*fp)(A);
    Bar(R(*f)(A)) : fp(f) { }
    // ...
    };
    

Как видите, первый подход гораздо более общий, так как мы можем специализироваться Foo за любой Тип функции нам нравится. Напротив, прямой шаблон во втором примере сложно связан с деталями сигнатуры функции и не может быть легко обобщен.

3

По вопросам рекламы [email protected]