При ответе this SO question я нашел в стандарте (уже C++ 03, еще в C++ 11), что вы можете использовать только адреса в качестве аргументов шаблона, отличных от типа, если они есть форма & id-expression
(плюс некоторые исключения).Указатель как аргумент шаблона непигового типа
Но я не мог ответить почему это случай.
аргументы14.3.2 шаблона не-типа [temp.arg.nontype]
Шаблон-аргумент для не-типа, не-шаблон Шаблон-параметр должен быть одним из:
[...]
- константа, выражение (5,19), что обозначает адрес объекта со статическим хранением> продолжительностью и внешней или внутренней связью или функцией с внешней или внутренней связью, в том числе шаблонов функций и шаблон функции -иды, но luding non-static class members, выражает (игнорируя круглые скобки) как & id-выражение, за исключением того, что & может быть опущен, если имя относится к функции или массиву и должно быть опущено, если соответствующий шаблон-параметр является ссылкой; [...]
(n3485, курсив мой)
Пример:
using TFoobar = int (*)();
template < TFoobar tp > struct foo_struct{};
int foobar() { return 42; }
constexpr TFoobar pFoobar = &foobar;
foo_struct < &foobar > o0; // fine
foo_struct <pFoobar> o1; // ill-formed
Я предполагаю, что это что-то делать с фазами перевода, а именно компилятор ничего не знает о адресах. Но почему это не разрешено? Должна ли компилятор использовать что-то похожее на макроподстановку, чтобы заменить pFoobar
на &foobar
?
Очень хороший вопрос. –
Я бы предположил, что это вопрос внесения консервативных изменений.C++ 11 полон действительно строгие способы для языка делать вещи, чтобы облегчить работу компилятора. Возможно, возможно расширить C++ 11, чтобы разрешить вышеупомянутое, но это вопрос для C++ 14 или за его пределами! – Yakk
[Есть предложение] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html), чтобы удалить эти ограничения. – dyp