Учитывая возможный тип функции varargs, возможно, cv-qualifier-seq и, возможно, ref-qualifier, можно написать характеристику типа, которая разбивает все квалификаторы без записи 4 * 3 * 2 = 24 частичных специализаций?
template<class T>
struct strip_function_qualifiers;
template<class R, class... Args>
struct strip_function_qualifiers<R(Args...)> { using type = R(Args...); };
template<class R, class... Args>
struct strip_function_qualifiers<R(Args..., ...)> { using type = R(Args..., ...); };
template<class R, class... Args>
struct strip_function_qualifiers<R(Args...) const> { using type = R(Args...); };
template<class R, class... Args>
struct strip_function_qualifiers<R(Args..., ...) const > { using type = R(Args..., ...); };
template<class R, class... Args>
struct strip_function_qualifiers<R(Args...) const &> { using type = R(Args...); };
template<class R, class... Args>
struct strip_function_qualifiers<R(Args..., ...) const & > { using type = R(Args..., ...); };
// etc. etc. for each possible combination (24 in total)
И с помощью новой транзакционной памяти TS добавив transaction_safe
в микс, означает ли это, что нам нужно будет написать 48 частичных специализаций для это?
Изменить. Указание описания этих странных типов функций ([dcl.fct]/p6, цитируя N4140):
Тип функции с cv-qualifier-seq или ref-qualifier (включая тип, названный typedef-name (7.1.3, 14.1)) только как:
- тип функции для нестатической функции-члена,
- тип функции, к которому относится указатель на элемент,
- тип функции верхнего уровня описания функции typedef или объявления alias,
- идентификатор типа в аргументе по умолчанию параметра типа (14.1) или
- идентификатор типа шаблона-аргумента для параметра типа (14.3.1).
[Пример:
typedef int FIC(int) const; FIC f; // ill-formed: does not declare a member function struct S { FIC f; // OK }; FIC S::*pm = &S::f; // OK
- конец примера]
Эффект cv-qualifier-seq в функции declarator - это не то же самое, что добавлять cv-квалификацию поверх тип функции. В последнем случае cv-квалификаторы игнорируются. [Примечание: тип функции, имеющий cv-qualifier-seq, не является cv-квалифицированный тип; не существует специальных типов функций cv. - конец примечание] [Пример:
typedef void F(); struct S { const F f; // OK: equivalent to: void f(); };
- конец примера]
Тип возврата, список параметров-параметров, ref-qualifier и cv-qualifier-seq, но не аргументы по умолчанию (8.3.6) или спецификация исключения (15.4), являются частью тип функции. [Примечание. Типы функций проверяются во время назначения и инициализации указателей на функции, ссылки к функциям и указателям на функции-члены. - конечная нота]