Начиная с некоторого кода метапрограммирования:
template<class... Ts>
class list {}; //a generic container for a list of types
template<class in_list_type>
class front //get the type of the first template parameter
{
template<template<class...> class in_list_less_template_type, class front_type, class... rest_types>
static front_type deduce_type(in_list_less_template_type<front_type, rest_types...>*);
public:
typedef decltype(deduce_type((in_list_type*)nullptr)) type;
};
Этот код отлично работает для этого:
typedef typename front<list<int, float, char>>::type type; //type is int
Но не компилируется, когда первый элемент является типом функции:
// no matching function for call to 'deduce_type'
typedef typename front<list<void (), float, char>>::type type;
У меня есть только доступ к XCode на данный момент, и я не могу подтвердить, является ли это просто ошибкой XCode. Я использую XCode 4.5.1, использую компилятор Apple LLVM 4.1.
Когда шаблон аргументов для deduce_type
выводятся, front_type
имеет void()
в качестве кандидата. Однако это сделало бы deduce_type
иметь тип void ()()
(функция, возвращающая функцию — alias<void()>()
если вы предполагаете template<typename T> using alias = T;
быть в области видимости). Это ошибка, и вывод типа завершается ошибкой.
Решение состоит в том, чтобы иметь deduce_type
вернуть что-то вроде identity<front_type>
, а также type
быть псевдонимом typename decltype(deduce_type((in_list_type*)nullptr))::type
,
Других решений пока нет …