Для понимания этих вопросов, пожалуйста, убедитесь, что знаете знания о метапрограммировании с сохранением состояния, тогда мы go.
Приведем цитаты о точке создания аргументов по умолчанию
[temp.point ] / 2
Если шаблон функции или функция-член шаблона класса вызывается способом, который использует определение аргумента по умолчанию для этого шаблона функции или функции-члена, точка создание аргумента по умолчанию является точкой создания шаблона функции или специализации функции-члена.
Если я правильно понимаю о приведенной выше цитате, это означает, что POI аргумента по умолчанию такой же, как POI шаблона функции, который использует аргумент по умолчанию (или, если я неправильно понимаю этот пункт, пожалуйста, поправьте меня).
Теперь готовы рассмотреть приведенные ниже коды:
#include <iostream>
template<int N>
struct state {
friend auto call(state<N>);
};
template<int N>
struct add_state {
friend auto call(state<N>) {
return N;
}
static const int value = N;
};
template<typename T, int N>
T show(int = add_state<N>::value) {
return T{};
}
int main() {
show<int, 0>();
call(state<0>{});
}
На самом деле приведенный выше код корректен (результат здесь godbolt ). Однако, по в приведенной выше цитате POI add_state<0>
будет таким же, как и у show<int, 0>()
, POI show<int, 0>()
либо после function main
, либо в конце единицы перевода (возможно, большинство компиляторов принимают конец перевода единица в качестве POI для шаблона функции), однако в этот момент вызов call(state<0>{});
не может найти определение call(state<0>{})
, поэтому он будет некорректным.
результат приведенного выше кода доказал, что POI add_state<0>
должен предшествовать вызову call(state<0>{})
, только в этой ситуации можно найти определение call(state<0>{})
. Так что меня смущает, Как интерпретировать этот вопрос, я ценю за правильные интерпретации.