非类型参数模板.为什么是全局和引用
Non-type parameter templates. Why global and reference?
template<typename Body>
Body solve(Body a, Body b){
Body zero(0);
return zero;
}
template<typename Body, Body& zero>
Body solve(Body a, Body b){
return zero;
}
complex<double> zero(0);
int main() {
complex<double> c1(1,2);
complex<double> c2(3,4);
solve<complex<double>, zero_complex> (c1,c2);
return 0;
}
嗨,我编译了上面的代码,它是OK的(我省略了细节在这里)。现在,我注意到zero
必须是一个全局变量,而且模板必须通过引用获得zero
。否则会导致编译错误。我使用c++11。
请告诉我为什么一定是这样:
- 通过引用 传递全局变量
指向模板的指针形参和引用形参的目的是允许你编写函数(或类),它们的不同之处在于它们所使用的全局状态。
它们所使用的状态的位置成为它们类型(或名称)的一部分,必须在编译/链接/加载时确定。
局部变量(在堆栈上)有一个不同的位置——而不是一个常量。无法在编译/链接/加载时确定位置。
标准还限制了可以作为模板参数传递的字面值。这背后的原因之一是,所讨论的符号的链接时间名称成为其非类型参数的函数:并且以唯一的方式命名Body
的每个实例很难。
为了避免这个问题,它们只允许有限的一组值作为非类型模板形参传递:引用、指针和整型值。
可能double
的问题是编译时和运行时的双精度和行为可能不同,这将使行为标准化变得棘手。所以,标准就禁止了double和float。
函子是无状态的,并且有一个返回Body
的const operator()
。
您可以使用引用作为模板参数,这就是您在这里所做的。但是,您引用的变量必须具有外部链接,而局部变量根本没有任何链接。
其他可以使用的非类型模板实参是指针和整型,如int。你的同样的例子可以这样写:
template<typename Body>
Body solve(Body a, Body b){
Body zero(0);
return zero;
}
template<typename Body, Body* zero>
Body* solve(Body a, Body b){
return zero;
}
int i = 0;
int main() {
solve<int, &i>(10, 20);
}
相关文章:
- QT C++中对全局变量的未定义引用
- 使用全局 std::array 引用作为模板参数时如何简化参数?
- 对全局变量的非常量引用的初始化无效
- 在函数中用不同的名称引用全局向量
- C++/Arduino 如何从类内部引用全局
- 使用全局引用调用函数时访问冲突
- 全局引用全局对象
- 将全局变量作为常量引用传递
- 使用 "::member" 引用全局命名空间有什么用吗?
- 为什么我不能使用 constexpr 全局变量来初始化 constexpr 引用类型
- 如何获取LLVM中指令引用的所有全局变量
- 是否可以通过引用将方法从类传递到全局函数或在类之间传递?
- 用ASMJIT引用全局变量
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- JNI/Android NDK-维护全局对象引用
- GCC链接器抱怨对现有全局变量的未定义引用
- 简单的引用变量赋值导致对象的全局指针出现segfault
- C++创建对象的全局引用
- JNI保留对对象的全局引用,并使用其他JNI方法访问它.在多个JNI调用中保持C++对象的活动状态
- 在 中全局引用捕获 lambda C++抑制别名优化