Неожиданное поведение с псевдонимом типа шаблона в VS2015

Следующий код компилируется с сообществом 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> (или я не прав с этим?).

  • Я нашел магический обходной путь?
  • Это новое поведение из стандарта C ++ 14?
  • Или это просто ошибка компилятора?

Изменить: Следующая более упрощенная версия не компилируется.

#include <functional>
#include <iostream>

template<typename T>
using Func = std::function<void( T )>;

int main()
{
Func<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
  • Так почему код выше компилируется и работает так, как я ожидал?
  • Это правильная реализация, если нет, то как бы это выглядело?

12

Решение

Или это просто ошибка компилятора?

Тот. Как упомянуто @ T.C., CWG # 577 актуально:

[…] там
была выражена некоторая озабоченность по поводу обработки шаблонов функций
и функции-члены шаблонов классов, если правило C ++ было изменено:
для параметра шаблона T, будет функция, принимающая один параметр
типа T стать функцией без параметров, если она была создана с
T = void?

Это обоснованная жалоба, но, к сожалению, для вас, функции-члены / шаблоны функций-членов и тип-идентификаторs были затронуты в равной степени резолюции:

Список параметров, состоящий из одного безымянного параметра независимый тип void эквивалентно пустому списку параметров.

таким образом, оба ваших фрагмента плохо сформированы, так как тип параметра действительно зависит.


Это правильная реализация, если нет, то как бы это выглядело?

Там нет правильной реализации. Если вам нужен тип функции с пустым списком параметров, вы должны указать его независимо от параметров шаблона.

Так почему код выше компилируется и работает так, как я ожидал?

Мое лучшее предположение: VC ++ делает замену void_template_alias_t<T> после гарантируя, что тип параметра не является зависимый тип «cv void«, но прежде чем сделать»void -> преобразование пустого списка «. Однако часто трудно понять, как VC ++ (или любой другой компилятор, в этом отношении) мыслит внутренне.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]