Следующий код компилируется с сообществом VS15 и выводит «Hello».
#include <functional>
#include <iostream>
template<typename T>
using void_template_alias_t = void;
template<typename T>
using Func = std::function<void( T )>;
template<typename T>
using FuncVoid = Func<void_template_alias_t<T>>;
int main()
{
FuncVoid<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
Я думаю, что это не разрешено компилировать.
Я играл, код был немного сложнее. Я наивно ожидал, что это сработает, но вдруг понял, что этот код не должен компилироваться, потому что вы не можете сделать Func<void>
(или я не прав с этим?).
Изменить: Следующая более упрощенная версия не компилируется.
#include <functional>
#include <iostream>
template<typename T>
using Func = std::function<void( T )>;
int main()
{
Func<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
Или это просто ошибка компилятора?
Тот. Как упомянуто @ T.C., CWG # 577 актуально:
[…] там
была выражена некоторая озабоченность по поводу обработки шаблонов функций
и функции-члены шаблонов классов, если правило C ++ было изменено:
для параметра шаблонаT
, будет функция, принимающая один параметр
типаT
стать функцией без параметров, если она была создана с
T = void
?
Это обоснованная жалоба, но, к сожалению, для вас, функции-члены / шаблоны функций-членов и тип-идентификаторs были затронуты в равной степени резолюции:
Список параметров, состоящий из одного безымянного параметра независимый тип
void
эквивалентно пустому списку параметров.
таким образом, оба ваших фрагмента плохо сформированы, так как тип параметра действительно зависит.
Это правильная реализация, если нет, то как бы это выглядело?
Там нет правильной реализации. Если вам нужен тип функции с пустым списком параметров, вы должны указать его независимо от параметров шаблона.
Так почему код выше компилируется и работает так, как я ожидал?
Мое лучшее предположение: VC ++ делает замену void_template_alias_t<T>
после гарантируя, что тип параметра не является зависимый тип «cv void
«, но прежде чем сделать»void
-> преобразование пустого списка «. Однако часто трудно понять, как VC ++ (или любой другой компилятор, в этом отношении) мыслит внутренне.
Других решений пока нет …