Tho*_*son 1 c++ templates types
这个问题源于需要调用传统的C例程(FFTW),它们在模板化的C++类中具有不同的函数名称,具体取决于类型(单/双/四倍精度).这个错误的代码示例给出了我可能想要做的一个简单示例:
#include <cstdio>
#include <cmath>
#include <typeinfo>
#include <cstdlib>
void fcnd(double *x) {
*x = pow(*x, 2);
printf("%f\n", *x);
}
void fcnf(float *x) {
*x -= 1;
printf("%f\n", *x);
}
template <typename T> class Class {
public:
void fcn() {
T *var;
if (typeid(T) == typeid(float)) {
var = (float *) malloc(sizeof(float));
} else if (typeid(T) == typeid(double)) {
var = (double *) malloc(sizeof(double));
}
*var = 1.0;
if (typeid(T) == typeid(float)) {
fcnf(var);
} else if (typeid(T) == typeid(double)) {
fcnd(var);
}
free(var);
}
};
int main() {
Class<double> x;
Class<float> y;
x.fcn();
y.fcn();
}
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会抱怨:
test.cpp: In instantiation of 'void Class<T>::fcn() [with T = double]': test.cpp:42:11: required from here test.cpp:22:17: error: cannot convert 'float*' to 'double*' in assignment
var = (float *) malloc(sizeof(float));
^ test.cpp:30:17: error: cannot convert 'double*' to 'float*' for argument '1' to 'void fcnf(float*)'
fcnf(var);
^ test.cpp: In instantiation of 'void Class<T>::fcn() [with T = float]': test.cpp:43:11: required from here test.cpp:24:17: error: cannot convert 'double*' to 'float*' in assignment
var = (double *) malloc(sizeof(double));
^ test.cpp:32:17: error: cannot convert 'float*' to 'double*' for argument '1' to 'void fcnd(double*)'
fcnd(var);
^
Run Code Online (Sandbox Code Playgroud)
现在,我知道这里的错误是什么.我的问题是,为什么C++不允许这样做?当然这是安全的,对吧?我认为专业化在这里可能有所帮助,总是正确的方法吗?
在C++ 17中,可以按如下方式调用基于模板参数的函数:
template <typename T> class Class
{
public:
void fcn()
{
// one line can do it
T* var{ reinterpret_cast<T*>(std::malloc(sizeof(*var))) };
*var = 1.0;
// C++17's if constexpr does exactly what you need
if constexpr (std::is_same_v<T, float>)
{
fcnf(var);
}
else if constexpr (std::is_same_v<T, double>)
{
fcnd(var);
}
free(var);
}
};
Run Code Online (Sandbox Code Playgroud)
如果您没有可用的C++ 17,则可以使用基于T模板特化的调度程序或仅使用简单的重载函数.
auto set(float* f) noexcept
{
return fcnf(f);
}
auto set(double* d) noexcept
{
return fcnd(d);
}
template <typename T> class Class
{
public:
void fcn()
{
T* var{ reinterpret_cast<T*>(std::malloc(sizeof(*var))) };
*var = 1.0;
set(var); // there's a reason we have function overloading in C++
free(var);
}
};
Run Code Online (Sandbox Code Playgroud)
注意:我希望在您的真实代码中检查调用的结果std::malloc().