如何将浮点数作为模板参数传递
How can I pass floating point numbers as template parameters?
我正在进行一个元编程项目,我们希望能够将浮点数作为模板参数传递。我不确定这个问题是否更适合Stack Exchange,但我认为它有点概念性,所以选择了这个网站。
基本上,我想这样做:
template <double var>
double fun() { return var; }
int main()
{
double myDoble = fun<1.0>();
return 0;
}
显然,这是不可能的。这个链接(http://en.cppreference.com/w/cpp/language/template_parameters)清楚地表明,作为模板参数传递的类型必须是以下类型之一:
integral type
enumeration
pointer to object or to function
lvalue reference to object or to function
pointer to member object or to member function
std::nullptr_t (since C++11)
然而,我可以传递指向对象的指针(可能是指向包含双精度体的结构体的指针?)这一事实使我怀疑,通过传递指向这种双精度体的指针,可能有一种方法可以实现上述目的。
所以我试了这个:
template <double* pVar>
double fun()
{
return *pVar;
}
int main() {
static const double param = 1.2;
double value = fun<¶m>();
return 0;
}
给出如下错误:
prog.cpp:9:29: error: ‘& param’ is not a valid template argument of type ‘double*’ because ‘param’ has no linkage
double value = fun<¶m>();
我认为问题可能是我使用了一个原语,所以我尝试了这个:
struct D
{
double val;
};
template <D* pD>
double fun()
{
return pD->val;
}
int main() {
static const D d{1.2};
double value = fun<&d>();
return 0;
}
给出相同的错误。
对于解决这个问题,有人有其他的想法吗?如果人们能克制自己不要回答"这是不可能的",我会很感激;我知道这是不可能的,但我还是想做!div;)如果你真的想传递double's给模板化的函数,你应该使用包装器。像这样:
struct D
{
operator double(){ return 1.2; }
};
template <typename T>
double fun()
{
T t;
return t;
}
int main()
{
double value = fun<D>();
return 0;
}
但也许更有用的是定义一个宏,像这样:
#define DBLWRAPPER(dbl) typedef struct { operator double(){ return dbl; } }
int main()
{
DBLWRAPPER(1.2) DBL1_2;
DBLWRAPPER(2.45) DBL2_45;
double value1_2 = fun<DBL1_2>();
double value2_45 = fun<DBL2_45>();
return 0;
}
这个适合我:
template <double* pVar>
double fun()
{
return *pVar;
}
double param = 1.2;
int main() {
double value = fun<¶m>();
return 0;
}
我使用的是g++ 4.8.2
这里的问题是只有带链接的对象才能用作模板非类型地址参数,我们可以通过c++标准草案14.3.2
模板非类型参数看到这一点,其中说(强调我的):
非类型、非模板模板形参的模板实参应为:
,并包括以下项目符号:
指定对象地址的常量表达式(5.19)静态存储时长,外部或内部链接或a带有外部或内部链接的功能[…]
这正是你的错误所说的:
[…因为' param '没有链接
,我们可以看到块作用域变量除了一些例外没有链接,这在3.5
程序和链接一节中有介绍,其中说:
未被这些规则覆盖的名称没有链接。此外,除了注意,在块作用域(3.3.3)声明的名称没有链接。一个类型当且仅当:
,不包括任何例外情况。
全局声明,可以解决这种情况下的问题:
static double param = 1.2;
int main()
{
double value = fun<¶m>();
return 0;
}
如果您希望*pVar
是一个编译时常数,以优化fun()
并在仅接受常数的地方使用它(例如作为模板参数或数组维度),您需要接受它为const double* const
并使param
为constexpr
(下面的代码也在ideone.com这里)…
template <int n>
struct S { };
template <const double* const pVar>
double fun()
{
S<(int)*pVar> s;
return *pVar;
}
constexpr double param = 1.2;
int main()
{
double value = fun<¶m>();
}
请注意,如果代码中的不同位置为模板提供指向具有相同值的不同double
的指针,那么您可能会在可执行文件中获得不同的实例化(即无意义的"代码膨胀",特殊化尝试失败…)。
c++ 11的解决方案(将float编码为int):
constexpr int f2i_scaler = 100000;
constexpr int operator"" _i(long double v)
{
return v * f2i_scaler < std::numeric_limits<int>::max() ||
v * f2i_scaler > std::numeric_limits<int>::lowest()
? v * f2i_scaler
: throw std::invalid_argument("Overflow!");
}
template <int n>
struct S {
void show(){
std::cout << (double)n/f2i_scaler << "n";
}
};
S<1.5_i> s;
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 使用指向成员的指针将成员函数作为参数传递
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 在 Cython 中传递浮点数组的最佳选择
- 在C++中将浮点数组的参数填充为 float*
- 如何在 Qml 沙德效果中将统一浮点数组传递给片段着色器?
- 在张量流C++中将浮点数的向量传递给张量
- 将枚举作为浮点数传递
- 参数传递转换浮点错误
- 在 C++ main 中将浮点表作为参数传递
- 管理C++传递浮点 *OUT 作为参数
- 如何将浮点数作为模板参数传递
- 通过python扩展/包装器传递浮点数组指针- sndobj库
- 将值从浮点数组传递到双精度数组时的奇怪行为(C, c++)
- 如何正确地将浮点数从c#传递到c++ (dll)
- 浮点数组作为c++的默认参数