Ответ 1
Первый фрагмент верен в С++ 17, но не в С++ 14 и 11.
Для С++ 14, [temp.arg.nontype]/1 говорит:
Аргумент шаблона для непигового, не-шаблона template-parameter должен быть одним из:
[...]
- постоянное выражение (5.19), которое обозначает адрес полного объекта со статическим временем хранения и внешним или внутренним связь или функция с внешней или внутренней связью, включая шаблонов функций и шаблонов-шаблонов функций, но исключая нестатические члены класса, выраженные (игнорируя круглые скобки) как
&
id-expression, где id-выражение - это имя объекта или функции, за исключением того, что&
может быть опущено, если имя ссылается на функции или массива и должны быть опущены, если соответствующие шаблон-параметр является ссылкой; или- константное выражение, которое вычисляет значение нулевого указателя (4.10); или
- константное выражение, которое вычисляет значение указателя нулевого элемента (4.11); или
- указатель на элемент, выраженный как описано в 5.3.1; или
- постоянное выражение типа
std::nullptr_t
.
(Я включил только те пули, которые имеют непосредственное отношение к указателям и указателям для членов.)
В принципе, адрес функции в вашем примере должен быть выражен строго как &fn
или fn
.
С++ 11 содержит по существу одну и ту же формулировку минус несколько разъяснений, введенных отчетами о дефектах между 11 и 14:
Для С++ 17 ограничения были смягчены в результате принятия бумаги N4268 (обоснование в N4198). Соответствующий пункт (2) теперь говорит:
Аргумент шаблона для параметра шаблона, не относящегося к типу, должен быть преобразованное постоянное выражение (5.20) типа Шаблон-параметры. Для шаблона-шаблона, не относящегося к типу ссылки или тип указателя, значение константного выражения не должно ссылаться на (или для типа указателя, не должен быть адресом):
- подобъект (1.8),
- временный объект (12.2),
- строковый литерал (2.13.5),
- результат выражения
typeid
(5.2.8) или- предопределенная переменная
__func__
(8.4.1).[Примечание. Если аргумент template представляет собой набор перегруженных функции (или указатель или указатель элемента к такому), соответствие функция выбрана из набора (13.4). - конечная нота]
N4198 содержит хорошие пояснения для каждой из этих пуль.