Правила определения набора типов функций, совместимых с std :: function <R (T1, T2)>? - PullRequest
5 голосов
/ 28 ноября 2011

Предположим, если у меня есть это,

std::function<int(int,int)> fs;

, то как я могу определить набор функций (или функциональных объектов), с которыми fs может быть инициализирован?

Какой изРазрешено следующее, а что нет:

std::function<int(int,int)> fs = [](int, int) { return int(10); };
std::function<int(int,int)> fs = [](char, char) { return char(10); };
std::function<int(int,int)> fs = [](int, short) { return int(10); };
std::function<int(int,int)> fs = [](double, int) { return float(10); };
std::function<int(int,int)> fs = [](int, wchar_t) { return wchar_t(10); };

std::function<int(int,int)> fs = [](const char*, int){ return "string"; };
std::function<int(int,int)> fs = [](const char*, int){ return 10; };
std::function<int(int,int)> fs = [](const char*, int){ return std::string(); };

Конечно, я могу скомпилировать и посмотреть, какой из них компилируется нормально, а какой нет.Но это не помогает мне понять различия в типах параметров и типе возвращаемого значения.Как далеко я могу пойти, чтобы использовать различные типы для них?

Иными словами, если я дал функцию (или функциональный объект), как я могу определить во время компиляции, совместима ли она с std::function<int(int,int)> или нет?У меня мало понимания, но я не достаточно уверен в этом.

Поэтому, пожалуйста, помогите мне понять и изложить правила определения набора типов функций, совместимых с std::function<R(T1,T2)>?Может ли метапрограммирование помочь мне здесь уведомлять пользователей, генерируя красивые сообщения об ошибках, если они используют несовместимую функцию?

Кстати, первая группа кажется совместимой: http://ideone.com/hJpG3

Ответы [ 2 ]

4 голосов
/ 28 ноября 2011

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

template <class _F, class ..._Args> struct __invokable;
template <class _F, class ..._Args> struct __invoke_of;

http://llvm.org/svn/llvm-project/libcxx/trunk/include/type_traits

Я использовал их для создания личной "черты члена" std::function:

template <class _F, bool = __invokable<_F&, _ArgTypes...>::value>
    struct __callable;

http://llvm.org/svn/llvm-project/libcxx/trunk/include/functional

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

Если вы хотите использовать эти черты, код с открытым исходным кодом. Но я был бы признателен, если вы уважаете лицензию с открытым исходным кодом, включив информацию об авторских правах в каждый файл.

4 голосов
/ 28 ноября 2011

Объект (указатель на функцию или функтор) должен быть Callable с данными типами аргументов, т. Е. fun( declval< Types >() ... ) правильно сформирован и неявно преобразован в R.

См. C ++ 11 §20.8.В частности 2;он дает различные особые случаи для указателей на члены и т. д. §20.8.11.2 / 2 и 20.8.11.2.1 / 7 связывают это с конструктором std::function.

...