非类型指针和引用模板参数以及 how/why 它们在编译时解析。 C++
Non-type pointer and reference template parameters and how/why they are resolved at compile time. c++
我只问为什么允许通过非类型模板传递 object/primitive 的内存位置,而我传统上希望在运行时分配和使用内存。我知道传递内存的变量必须具有外部链接,但是鉴于此,这是否意味着外部链接变量的内存位置始终不变?
举例说明:
template<std::string *temp>
void f();
通过模板传递的内存位置不会在每次执行程序时都不同,因此不是编译时常量,因为我认为非类型参数需要模板吗?
此类事情由 运行time 加载程序执行的修复处理,地址确实会在 运行time 发生变化,但地址的位置会有所不同相对于加载的可执行映像始终位于固定位置。
例如 ELF 图像格式(最近在 *nix 上很常见)有重定位部分,它告诉加载程序在程序中哪里有需要以某种方式更改的值。编译器和链接器一起写入足够的信息,使链接器能够在 运行 时间生成最终值。
假设你有函数:
void Foo::Bar() { }
然后将其作为模板参数传递(非常人为):
template<typename Class>
struct invoke {
template<void (Class::*Fn)()>
void do_fn(Class * ptr ) { (ptr->*Fn)(); }
};
..
Foo f;
invoke<Foo>::do_fn<&Foo::Bar>(&f);
Foo::Bar 和实例化将在可执行映像中的某个特定地址找到,重定位将告诉实例化的 do_fn 如何调用实际函数。并注意 do_fn 函数名称本身不需要 运行 时间地址,名称只需要以某种方式计算,所有 invoke::do_fn<&Foo::Bar>( ) 调用可以解析为单个专门化(每个翻译单元可能有一个实例化,但链接器需要能够根据单一定义规则丢弃除一个之外的所有实例,最好是不重要的情况选择了哪个实例化)。
我只问为什么允许通过非类型模板传递 object/primitive 的内存位置,而我传统上希望在运行时分配和使用内存。我知道传递内存的变量必须具有外部链接,但是鉴于此,这是否意味着外部链接变量的内存位置始终不变? 举例说明:
template<std::string *temp>
void f();
通过模板传递的内存位置不会在每次执行程序时都不同,因此不是编译时常量,因为我认为非类型参数需要模板吗?
此类事情由 运行time 加载程序执行的修复处理,地址确实会在 运行time 发生变化,但地址的位置会有所不同相对于加载的可执行映像始终位于固定位置。
例如 ELF 图像格式(最近在 *nix 上很常见)有重定位部分,它告诉加载程序在程序中哪里有需要以某种方式更改的值。编译器和链接器一起写入足够的信息,使链接器能够在 运行 时间生成最终值。
假设你有函数:
void Foo::Bar() { }
然后将其作为模板参数传递(非常人为):
template<typename Class>
struct invoke {
template<void (Class::*Fn)()>
void do_fn(Class * ptr ) { (ptr->*Fn)(); }
};
..
Foo f;
invoke<Foo>::do_fn<&Foo::Bar>(&f);
Foo::Bar 和实例化将在可执行映像中的某个特定地址找到,重定位将告诉实例化的 do_fn 如何调用实际函数。并注意 do_fn 函数名称本身不需要 运行 时间地址,名称只需要以某种方式计算,所有 invoke::do_fn<&Foo::Bar>( ) 调用可以解析为单个专门化(每个翻译单元可能有一个实例化,但链接器需要能够根据单一定义规则丢弃除一个之外的所有实例,最好是不重要的情况选择了哪个实例化)。