компилятору не нужно знать значение из &a
во время компиляции не больше, чем нужно для адреса функций.
Подумайте об этом так: компилятор будет создавать шаблон функции с &a
в качестве параметра и сгенерировать «объектный код» (в любом формате, который он использует для перехода к компоновщику). Код объекта будет выглядеть (ну это не будет, но вы получите идею):
func f__<funky_mangled_name_to_say_this_is_f_for_&a>__:
reg0 <- /* linker, pls put &std::cout here */
reg1 <- /* hey linker, stuff &a in there ok? */
call std::basic_stream::operator<<(int*) /* linker, fun addr please? */
[...]
Если экземпляр f<b&>
, предполагая, что b
является еще одним глобальным статическим, компилятор делает то же самое:
func f__<funky_mangled_name_to_say_this_is_f_for_&b>__:
reg0 <- /* linker, pls put &std::cout here */
reg1 <- /* hey linker, stuff &b in there ok? */
call std::basic_stream::operator<<(int*) /* linker, fun addr please? */
[...]
И когда ваш код вызывает для вызова любой из этих:
fun foo:
call f__<funky_mangled_name_to_say_this_is_f_for_&a>__
call f__<funky_mangled_name_to_say_this_is_f_for_&b>__
Какая точная вызываемая функция кодируется во имя искаженной функции. Сгенерированный код не зависит от времени выполнения &a
или &b
. Компилятор знает, что во время выполнения будут такие вещи (вы сказали это так), вот и все, что нужно. Это позволит компоновщику заполнить пробелы (или кричать на вас, если вы не выполнили свое обещание).
Для вашего Кроме того, я боюсь, что я не достаточно хорошо знаком о правилах constexpr, но два компиляторы я должен сказать мне, что эта функция будет оцениваться во время выполнения, которые, по их мнению, делает код несоответствие. (Если они не правы, то выше ответ, по крайней мере, неполным.)
template <int* p, int* pp>
constexpr std::size_t f() {
return (p + 1) == (pp + 7) ? 5 : 10;
}
int main() {
int arr[f<&a, &b>()] = {};
}
лязг 3,5 в 14 стандартов C++ соответствующий режим:
$ clang++ -std=c++14 -stdlib=libc++ t.cpp -pedantic
t.cpp:10:10: warning: variable length arrays are a C99 feature [-Wvla-extension]
int arr[f<&a, &b>()];
^
1 warning generated.
НКУ г ++ 5.1, тот же режим :
$ g++ -std=c++14 t.cpp -O3 -pedantic
t.cpp: In function 'int main()':
t.cpp:10:22: warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[f<&a, &b>()];
В г ++, имя переменной, адрес которой будет принято искажаются во имя функции: http://coliru.stacked-crooked.com/a/ee352366c870c010 – dyp
@dyp Это имеет смысл! – Lingxi
@ dyp Компилятор в конечном итоге скорректирует значение адреса 'p' в двоичном коде экземпляра шаблона. Могу я понять это так? – Lingxi