作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个通用函数可以从我的数据库中读取列。它在头文件中的原型(prototype)是:
template <typename T> void sqlite3_column_template(sqlite3_stmt *stmt, int column, T& value);
这个想法是根据值类型专门化这个函数来调用这些函数:
sqlite3_column_int64(...)
sqlite3_column_double(...)
sqlite3_column_text(...)
在我的 cpp
文件中,我编写了这样的特化函数:
template <> void sqlite3_column_template(sqlite3_stmt *stmt, int column, int& value)
{
value = sqlite3_column_int64(stmt, column);
}
template <> void sqlite3_column_template(sqlite3_stmt *stmt, int column, float& value)
{
value = sqlite3_column_double(stmt, column);
}
template <> void sqlite3_column_template(sqlite3_stmt *stmt, int column, std::string& value)
{
value = reinterpret_cast<const char*>(sqlite3_column_text(stmt, column));
}
我遇到的问题是调用此函数时的值类型可以是以下几种:
uint32_t, int32_t, int64_t
float, double
我不知道如何判断所有“整数”类型都必须调用函数sqlite3_column_int64
。
对于 float
和 double
调用 sqlite3_column_double
函数也是一样的。
我该怎么做?有可能吗?
我使用的解决方案如下:
// the 3 functions in the header file
template <typename T>
std::enable_if_t<std::is_integral_v<T>> sqlite3_column_template(sqlite3_stmt *stmt, int column, T& value)
{
value = sqlite3_column_int64(stmt, column);
}
template <typename T>
std::enable_if_t<std::is_floating_point_v<T>> sqlite3_column_template(sqlite3_stmt *stmt, int column, T& value)
{
value = sqlite3_column_double(stmt, column);
}
template <typename T>
std::enable_if_t<std::is_same_v<T, std::string>> sqlite3_column_template(sqlite3_stmt *stmt, int column, T& value)
{
value = reinterpret_cast<const char*>(sqlite3_column_text(stmt, column));
}
最佳答案
如果您有权访问 c++17 ,您可以在 if constexpr 的帮助下将特化组合到一个函数中。
Where 类型特征:
std::is_integral
已用于检查类型是否为整数。std::is_floating_point
已用于检查类型是否为 float 。std::is_same_v<T, U>
已经用过检查类型(即 T
和 U
)是否相同(用于检查 std::string
).sqlite3_column_template
现在可以写成:
#include <type_traits> // std::is_integral, std::is_floating_point, std::is_same
template <typename T>
void sqlite3_column_template(sqlite3_stmt *stmt, int column, T& value)
{
if constexpr (std::is_integral_v<T>)
{
value = sqlite3_column_int64();
// do something more
}
else if constexpr (std::is_floating_point_v<T>)
{
value = sqlite3_column_double();
// do something more
}
else if constexpr (std::is_same_v<T, std::string>)
{
value = sqlite3_column_text();
// do something more
}
else
static_assert(false, "wrong type");
}
关于c++ - 如何在同一个模板函数上专门化多个类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57393715/
我有一个带有模板函数的基类,该函数具有通用模板类型和专用版本。 #ifndef BASE_CLASS #define BASE_CLASS #include using namespace std;
我有这个 3D vector 模板 template class Vec3TYPE{ public: union{ struct{ TYPE x,y,z; }; struct{ TY
我是一名优秀的程序员,十分优秀!