用于各种参数类型的 C++ 类模板方法

标签 c++

我正在包装一些 sqlite 的东西,我想知道,也许使用模板,我是否可以避免用新方法包装每种类型。但是,我完全迷路了,摸索着模板。我找不到很好的教程。

这就是我的 Statement 类现在的样子

class Statement {
  public:
    Statement();
    ~Statement();
    void BindInt(int index, int value);
    void BindInt(std::string name, int value);
    void BindInt64(int index, int value);
    void BindInt64(std::string name, int value);
    void BindText(int index, std::string value);
    void BindText(std::string name, std::string value);
};
Statement::Statement(){}
Statement::~Statement(){}
void Statement::BindInt(int index, int value){}
void Statement::BindInt(std::string name, int value){}
void Statement::BindInt64(int index, int value){}
void Statement::BindInt64(std::string name, int value){}
void Statement::BindText(int index, std::string value){}
void Statement::BindText(std::string name, std::string value){}

我觉得我可以写一些通用的东西,比如

  class Statement {
      public:
        Statement();
        ~Statement();
        template<class T, class V>
        void Bind(T param, V value);
    };
    Statement::Statement(){}
    Statement::~Statement(){}
    template<class T, class V>
    void Statement::Bind(T index, T value){}

但我需要知道在 value 中传递的值类型,以便我可以调用正确的底层函数,例如 sqlite_bind_intsqlite_bind_text 等。这可能吗?

最佳答案

But I would need to know what type of value was passed in value ....

你确实知道类型。它是 V

... so I can call the correct underlying function, eg sqlite_bind_int or sqlite_bind_text, etc. Is this possible?

如果您需要为作为 value 传递的每种类型调用不同的方法,您不会从使用模板中获益太多。您最终会为每种可能的类型编写一个特化来调用相应的 sqlite_bind_XY 函数。您可以通过重载更轻松地获得相同的结果:

class Statement {
  public:
    Statement();
    ~Statement();        
    void Bind(int index, int value);               // aka BindInt
    void Bind(std::string name, int value);
    void Bind(int index, int64_t value);           // aka BindInt64
    void Bind(std::string name, int64_t value);    
    void Bind(int index, std::string value);       // aka BindText
    void Bind(std::string name, std::string value);
};

请注意,我必须将 int 更改为 int64_t 以使它们不同。您会遇到与模板相同的问题。有时没有明显的方法让参数不同,这时可以使用标签:

class Statement {
  public:
    struct text_tag{};
    struct int_tag{};
    struct int64_tag{};
    Statement();
    ~Statement();        
    void Bind(int_tag,int index, int value);               // aka BindInt
    void Bind(int_tag,std::string name, int value);
    void Bind(int64_tag,int index, int value);           // aka BindInt64
    void Bind(int64_tag,std::string name, int value);    
    void Bind(text_tag,int index, std::string value);       // aka BindText
    void Bind(text_tag,std::string name, std::string value);
};

作为一个 super 简化的经验法则,要持保留态度:当你想为每种类型做不同的事情时,使用重载;当你想为每种类型做同样的事情时,使用模板。

PS:正如@Mils Budnek 所指出的,“您的类 IMO 的界面稍微好一点,但在这种情况下,模板肯定不会导致更简单的代码。”我确实同意,但专注于提倡重载;)。

关于用于各种参数类型的 C++ 类模板方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54485580/

相关文章:

c++ - 找不到链接库的符号

c++ - 如何为自定义数组类创建一个构造函数,该构造函数可以接受任意数量的参数,直到数组的大小?

c++ - OpenCV C++ - 具有不规则边的矩形检测

c++ - Visual C++ - 计算目录中的文件

c++ - 检查一个字符串是否被另外两个字符串交错

C++ 处理为 HWND?

c++ - 检查输入值是整数类型

c++ - 将 std::vector<boost::variant<...>> 与 Google Mock 一起使用会导致编译错误

c++ - 如何在链表中重载运算符++

c# - c# 中的 System.Diagnostics.Process 和 c++ 中的 CreateProcess() 哪个是最佳选择?