データベースから列を読み取る汎用関数があります。ヘッダーファイルのプロトタイプは次のとおりです。
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));
}
SFINAEstd::enable_if
を使用して、型特性に基づいて過負荷解決から関数を条件付きで削除するために使用できます。
std::is_integral<T>
Tが整数型かどうかをチェックします。 std::is_floating_point<T>
Tが浮動小数点型かどうかをチェックします。enable_ifを使用した後のコード:
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);
}
void sqlite3_column_template(sqlite3_stmt *stmt, int column, std::string& value)
{
value = reinterpret_cast<const char*>(sqlite3_column_text(stmt, column));
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加