我正在做一些关于mysql C API封装的练习。当我决定编写这样的sql时。
template<class T> C_SQL& operator%(const char* txt)...;
template<class T> C_SQL& operator%(T& t)...;
template<class T> C_SQL& operator,(T& t)...;
Int kk;
Small jj;
C_SQL sql;
sql % "insert into test_table (tiny_col,short_col) values (" % kk , jj % ")" ;我的计划是,通过重载三个操作符,我可以获得如下的sql文本:
"insert into test_table (tiny_col,short_col) values (? , ?)" ,并创建一些引用客户端变量地址的绑定变量,如kk、jj。
我的问题是:
由于运算符% ()的优先级高于运算符,(),jj坚持使用")“%,编译错误报告类Small没有运算符%。
怎么办?通过编写命令让char*、kk、jj和char*进入sql对象。
发布于 2013-07-19 11:48:03
怎么办?
你不能。没有办法改变C++运算符的优先顺序。
即使你可以,这可能也不是一个好主意。像这样重载随机操作符被认为是不好的做法。
我建议坚持C++约定,到处使用<< (因为我不清楚为什么需要多个不同的运算符)。
然而,这里根本不清楚为什么你需要操作符重载。对我来说,这段代码会写得更清楚:
sql = bind("insert into test_table (tiny_col,short_col) values (?,?)", kk, jj);发布于 2013-07-19 14:57:56
#include <iostream>
#include <string>
#include <boost/tuple/tuple.hpp>
class C_SQL
{
public:
C_SQL& operator%(const char* txt){
text_ += txt;
return *this;
}
template <typename Tuple>
C_SQL& operator%( const Tuple& t )
{
text_+="values(" ;
return bind_tuple_helper<Tuple,boost::tuples::length<Tuple>::value>::bind( *this, t );
}
private:
template <typename Tuple, size_t size>
struct bind_tuple_helper {
static C_SQL& bind( C_SQL& s, const Tuple& t ) {
//text appends
s.text_+='?' ;
//deal with a variable , this is a test
std::cout<< boost::get<boost::tuples::length<Tuple>::value - size>(t) << std::endl;
//text appends
if (size != 1){
s.text_+=',' ;
}
//another var
return bind_tuple_helper<Tuple,size-1>::bind( s, t );
}
};
//terminator
template <typename Tuple>
struct bind_tuple_helper<Tuple,0> {
static C_SQL& bind( C_SQL& s, const Tuple& t ) {
s.text_ += ')';
return s;
}
};
std::string text_;
};
int main() {
#define values boost::make_tuple
int kk=1;
double jj=2;
long ll=3;
C_SQL sql;
sql % "insert int test_tbl (col1,col2,col3) " % values(kk,jj,ll) ;
return 0;
}发布于 2013-07-19 22:06:00
我已经完成了我的工作。现在我要解释一下为什么我不喜欢问号。
bind("select t1.c1,t1.c2 from t1,t2,t3 "
"where t1.c1=? and t1.c4 between ? and ?"
"t1.c1=t2.c1 and t2.c4=t3.c3 and t2.c3>?" , tt,hh,jj,aa,,rr);
bind("insert into t4 values(?,?,?,?,?,?,?,?,?,?,?,?)", kk,tt,aa,vv,cc,ee,zz,jj,oo);它更像是C语言风格,容易出错,而且你必须有一个好的视力(其中有2个错误,你能找出来吗?的数量?不等于提供的变量数量)
我选择了更多的C++风格。
template<class T0,class T1,class T2,class T3>
tuple<T0,T1,T2,T3> values(T0& t0,T1& t1,T2& t2,T3& t3)
{
using namespace boost;
return make_tuple(ref(t0),ref(t1),ref(t2),ref(t3));
}
class Small{...};
class Tiny {...};
class String{...};
class Datetime{...};
Small kk;
char buff[32];
String ss(buff,32); //Wrapper. like boost::asio::array
double dd; //primitive C++ type. does not support NULL field
Double bb; //Wrapper type. support NULL semantics
C_SQL sql;
sql % "insert int test_tbl (c1,c2,c3,c4)" % values(kk,ss,dd,bb) ;
C_SQL sql2;
sql2 % "select * from t1,t2 where t1.c1=" %kk%
"and t1.c2 between" %bb% " and " %dd%
"and t2.c2 = t1.c5"现在它更具可读性和清晰度了。
https://stackoverflow.com/questions/17737609
复制相似问题