Как мне создать класс function_list <> для хранения вектора std :: function <> с тем же синтаксисом шаблона? - PullRequest
1 голос
/ 16 июня 2019

Я хочу иметь шаблонный класс function_list <>, который содержит вектор значений std :: function <>. Ключевым моментом является то, что я хочу объявить мой список в той же форме, что и единый std :: function <>. например,

function_list<void()> functions; // list of std::functions that take and return void

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

#include <functional>
#include <vector>
#include <iostream>

template<class _R, class... _Args>
class function_list<_R(_Args...)>
{
public:
  std::vector<std::function<_R(_Args...)>> functions;
  function_list& operator+=(std::function<_R(_Args...)> f) { functions.push_back(f); return *this; }
  void call_all(_Args... args) { for (auto& f : functions) { f(args...); } }
};

int main()
{
  function_list<void()> fl;
  fl += []() { std::cout << "Hello, World!" << std::endl; };
  fl += []() { std::cout << "Goodbye, Cruel World!" << std::endl; };

  fl.call_all();

  return 0;
}

Это не компилируется и завершается ошибкой со следующими ошибками (лязг на OSX 10.14):

test.cpp:6:7: error: explicit specialization of non-template class 'function_list'
class function_list<_R(_Args...)>
      ^            ~~~~~~~~~~~~~~
test.cpp:9:28: error: function cannot return function type 'void ()'
        std::vector<std::function<_R(_Args...)>> functions;
                                  ^
test.cpp:14:24: note: in instantiation of template class 'function_list<void ()>' requested here
        function_list<void()> fl;
                              ^
2 errors generated.

Что я делаю не так? Спасибо за вашу помощь.

1 Ответ

5 голосов
/ 16 июня 2019

Я не понимаю, что не так с использованием std::vector<std::function<...>> напрямую, но вот ваш ответ:

template<class _R, class... _Args> class function_list<_R(_Args...)>

Это право есть специализация шаблона класса.

Но вам нужносначала объявите шаблон, чтобы иметь возможность его специализировать:

template <class> class function_list;

Но на самом деле вам даже не нужна специализация.Вы можете просто сделать:

template <class T> class function_list
{
  public:
    std::vector<std::function<T>> functions;
};

Также обратите внимание, что имена, начинающиеся с _, за которыми следует заглавная буква, зарезервированы и не должны использоваться.Вы должны переименовать параметры вашего шаблона.См https://en.cppreference.com/w/cpp/language/identifiers

...