c ++运算符混合使用和优先级不是我想要的

时间:2013-07-19 03:23:59

标签: c++ mysql operator-overloading

我正在做一些关于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 (? , ?)" ,

并创建一些绑定变量,这些变量引用客户端var的地址,如kk,jj。

我的问题是:

由于运算符%()的prioity高于运算符,(),jj坚持“)”% 并且complie错误抱怨类Small没有运算符%。

怎么办?让char *,kk,jj和char *通过编写命令进入sql对象。

3 个答案:

答案 0 :(得分:0)

  

怎么办?

你做不到。无法更改C ++运算符的优先顺序。

即使你可以,这可能是一个坏主意。像这样重载随机运算符被认为是不好的做法。

我建议坚持使用C ++约定,并在任何地方使用<<(因为我不清楚为什么你需要多个不同的运算符)。

然而,目前尚不清楚为什么你需要操作员重载。对我来说,这段代码将更清晰地写成:

sql = bind("insert into test_table (tiny_col,short_col) values (?,?)", kk, jj);

答案 1 :(得分:0)

#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;
}

答案 2 :(得分:0)

我完成了我的工作。现在我会解释为什么我不喜欢问号。

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个错误,你能找到它们吗? 数量?不等于提供的var的数量)

我选择了更多的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"

现在它更加简洁明了。