Шаблон Variadic с типом по умолчанию - PullRequest
3 голосов
/ 17 мая 2019

Я пытаюсь создать пакет параметров с типом указателя по умолчанию:

template<int*... T>
void f() {}

Я получаю ошибку с этим кодом:

int main(){
    int* a = new int(5);
    f<a>();
}

Но если я сделаю это, я не получу ошибку:

int main(){
    f<nullptr>();
}

Почему?

Ошибка:

./example.cpp: In function 'int main()': ./example.cpp:6:7: error: the
value of 'a' is not usable in a constant expression
     f<a>();
       ^ ./example.cpp:5:10: note: 'a' was not declared 'constexpr'
     int* a = new int;
          ^ ./example.cpp:6:10: error: no matching function for call to 'f<a>()'
     f<a>();
          ^ ./example.cpp:2:6: note: candidate: 'template<int* ...T> void f()'  void f() {}
      ^ ./example.cpp:2:6: note:   template argument deduction/substitution failed: ./example.cpp:6:10: error: 'a' is not a
valid template argument because 'a' is a variable, not the address of
a variable
     f<a>();
          ^ Compiler returned: 1

Проводник компилятора

1 Ответ

3 голосов
/ 17 мая 2019

Аргумент для нетипичного параметра шаблона должен быть константное выражение .

int* a = new int(5);

В этом фрагменте a не является константным выражением и не подходит для шаблонного нетипового параметра.

На самом деле это должно быть интуитивно приемлемо. Помните, что компилятору необходимо сгенерировать код для созданного шаблона, прежде чем программа сможет быть выполнена, и этот код должен будет использовать значение аргумента шаблона. Но значение a не известно во время компиляции - это может быть что угодно, в зависимости от того, где будет выделена память. Очевидно, что компилятор не может предсказать, какое это будет значение.

С другой стороны, адрес глобального (или статического) объекта можно использовать в качестве аргумента шаблона указателя нетипичного типа:

int k = 10;

int main(){
    f<&k>();
}

Вышеприведенный код работает, что интуитивно понятно, поскольку компилятор будет знать, где находится глобальный объект (компилятор сам поместит его туда!)

И последнее, но не менее важное: ваш заголовок не нужен. Эти правила применяются к невариантным шаблонам таким же образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...