"Inheriting"具有可变参数模板函数的类
"Inheriting" a class with variadic templated function
我想编写一个可以操作不同类型的数据库(例如sqlite,postgres等)的数据库包装器,因此无论用户实际使用什么数据库,用户编写的代码都不会改变。
在我的脑海中,这需要一个抽象的基类,如下所示:
class database {
public:
virtual bool query(const std::string &q) = 0;
// Other stuff
};
class sqlite : public database {
public:
bool query(const std::string &q) {
// Implementation
}
};
这看起来不错,但我正在使用可变参数模板来转义查询中的参数(我真的很喜欢这个想法,所以我想坚持下去!),所以不幸的是我的基类看起来像:
class database {
public:
template <typename... Args>
bool query(const std::string &q, const Args &... args) {
// Implementation
}
};
然而,这阻碍了创建抽象类,因为模板化函数不能是虚拟的。到目前为止,我唯一想到的是这个结构
template <class DatabaseType>
class database {
public:
template <typename... Args>
bool query(const std::string &q, const Args &... args) {
return database_.query(q, args...);
}
private:
DatabaseType database_;
};
虽然这似乎有效,但对于所有只调用同名database_
函数之外什么都不做的包装器,对我来说它看起来不是一个很好的风格。这是这里选择的设计模式,还是有更干净或更惯用的方式?
您可以从参数中生成一个查询对象给query
函数,并将其传递给虚拟query_impl
函数。
[...]有没有更干净,或更惯用的方式
您可能需要查找 CRTP 以实现模板的多态行为。
template <class concrete_db>
struct abstract_db {
template <typename... Args>
void query(std::string const& q, Args const&... args) {
static_cast<concrete_db *>(this)->query(q, args...);
}
};
struct postgres_db : abstract_db<postgres_db> {
template <typename... Args>
void query(std::string const& q, Args const&... args) {
// do something
}
};
相关文章:
- C++ gmock - 我们如何在单元测试 cpp 文件中读取/获取 cpp 文件函数的参数值
- 访问函数变体时"Invalid conversion"错误
- 创建函数变体向量时"No matching function for call"错误
- 如何使用 SFINAE 来防止模板函数变窄?
- 如何在 c++ 中将 1 个函数变量值发送到另一个函数
- C++记录每个函数和参数值
- 谷歌模拟函数改变参数值
- 将函数形参的实参解包到c++模板类
- 函数对象应该是函数实参还是它的引用?
- 如何传递操作符作为默认函函数实参
- c++ const函数形参.有没有一种方法可以只声明函数的单个签名?
- Const正确性- Const指针作为函数实参
- 关于将指向数组的指针作为函数形参的混淆
- 将非const引用使用auto-keyword声明的lambda作为实参传递给std::函数形参类型
- 通过函数实参而不是模板形参获取元组的元素
- 在函数实参中使用模板形参不适用gcc4.8
- 作为函数形参传递的Vector初始化器列表
- 指向函数形参的指针vs函数形参
- 在模板化类和函数上下文中以默认值作为函数形参的函子:-)
- 带std::函数形参的重载操作符