gpt4 book ai didi

c++ - 创建通用插入函数

转载 作者:太空宇宙 更新时间:2023-11-04 14:29:55 25 4
gpt4 key购买 nike

我试图创建一个通用函数,它可以获取表名和值并将插入返回到查询中,并想出了如下所示的内容:

    struct any {
enum type {Int, Float, String};
any(int e) { m_data.INT = e; m_type = Int;}
any(float e) { m_data.FLOAT = e; m_type = Float;}
any(char* e) { m_data.STRING = e; m_type = String;}
type get_type() const { return m_type; }
int get_int() const { return m_data.INT; }
float get_float() const { return m_data.FLOAT; }
char* get_string() const { return m_data.STRING; }
private:
type m_type;
union {
int INT;
float FLOAT;
char *STRING;
} m_data;
};
template<typename ...Args>
std::string GetInsertString(const std::string& tableName, Args... args)
{
std::string insertString = "INSERT INTO ";
insertString += tableName;
insertString += " VALUES(";
std::vector<any> vec = {args...};
std::ostringstream ss;
for (unsigned i = 0; i < vec.size(); ++i)
{
switch(vec[i].get_type())
{
case any::Int:
ss.str("");
ss << vec[i].get_int();
insertString += ss.str() + ",";
break;
case any::Float:
ss.str("");
ss << vec[i].get_float();
insertString += ss.str() + ",";
break;
case any::String:
ss.str("");
insertString += "'" + std::string(vec[i].get_string()) + "'," ;
break;
}
}
insertString.pop_back();
insertString += ");";
return insertString;
}

其中 any 是基于此链接的类 How can I iterate over a packed variadic template argument list?

但问题是我无法将 std::string 类型作为可变参数传递给此函数,因为我们在 any 类中有 union ,因此需要您的帮助伙计们传递 std::string 类型作为构造插入查询值的参数

最佳答案

您可以使用虚拟基类、模板包装器和智能指针编写一些如下内容

#include <string>
#include <vector>
#include <memory>
#include <sstream>
#include <iostream>


struct anyBase
{ virtual int unusedVirt () { return 0; }; };

template <typename T>
struct anyW : public anyBase
{
T val;

anyW (T const & v0) : val{v0} { }
};


struct any
{
public:
enum type { Int, Float, String };

any (int e)
: m_type{Int}, m_data{new anyW<int>(e)} { }

any (float e)
: m_type{Float}, m_data{new anyW<float>(e)} { }

any (char const * e)
: m_type{String}, m_data{new anyW<std::string>(e)} { }

any (std::string const & e)
: m_type{String}, m_data{new anyW<std::string>(e)} { }

any (any const & a) : m_type{a.m_type}, m_data{nullptr}
{
switch ( m_type )
{
case Int:
m_data.reset(new anyW<int>(a.get_int()));
break;

case Float:
m_data.reset(new anyW<float>(a.get_float()));
break;

case String:
m_data.reset(new anyW<std::string>(a.get_string()));
break;
}
}

type get_type () const { return m_type; }

int get_int () const
{ return dynamic_cast<anyW<int>*>(m_data.get())->val; }

float get_float () const
{ return dynamic_cast<anyW<float>*>(m_data.get())->val; }

std::string const & get_string () const
{ return dynamic_cast<anyW<std::string>*>(m_data.get())->val; }

private:
type m_type;

std::unique_ptr<anyBase> m_data;
};


template<typename ...Args>
std::string GetInsertString(const std::string& tableName, Args... args)
{
std::string insertString = "INSERT INTO ";
insertString += tableName;
insertString += " VALUES(";
std::vector<any> vec = {args...};
std::ostringstream ss;
for (unsigned i = 0; i < vec.size(); ++i)
{
switch(vec[i].get_type())
{
case any::Int:
ss.str("");
ss << vec[i].get_int();
insertString += ss.str() + ",";
break;
case any::Float:
ss.str("");
ss << vec[i].get_float();
insertString += ss.str() + ",";
break;
case any::String:
ss.str("");
insertString += "'" + std::string(vec[i].get_string()) + "'," ;
break;
}
}
insertString.pop_back();
insertString += ");";
return insertString;
}


int main ()
{
std::cout << GetInsertString("fooTable", 1, 2.2f, "3", std::string("4"))
<< std:: endl;
// print INSERT INTO fooTable VALUES(1,2.2,'3','4');
}

注意:

  • 此解决方案也适用于 C++11

  • 我统一了 char *std::string 的情况;我认为注册一个 chat *

  • 是个坏主意
  • 使用 std::unique_ptr 您需要 copy_constructor 因为 std::unique_ptr 中的复制构造函数被删除,因此删除了任何默认的复制构造函数也是

  • 更好的解决方案可能是等待传入(C++17,如果我没记错的话)std::variant

关于c++ - 创建通用插入函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42734382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com