I have the following problem:
Let's consider we have
#define SET callMe
#define COLUMN(x) #x
and in our main block of our program we have the following line:
SET(COLUMN(price)="hi");
which after the preprocessor running is translated to:
#callMe("price"="hi");
I need function callMe
signature to be callMe(string str)
so that leaves us to have to make something to make the "price"="hi"
to "price=hi"
and let callMe
function to handle the rest of the problem. Last thing to state is that all this program I describe is a part of a Table class.
The only option I have is overload the operator =
so the "price"="hi"
translated to the wanted one, but I can't get what I should overload because I first thought th开发者_如何学JAVAat doing the following overload
#std::string operator=(std::string str)
as a member function of the Table class but it seems I can't get it right on track.
Any clues of how I can achieve the wanted operations?
Is this any good to you?
#define SECOND_PASS(x) callMe(#x)
#define COLUMN(x) x
#define SET(x) SECOND_PASS(x)
which results in:
callMe("price=\"hi\"");
This essentially gets the preprocessor to remove COLUMN before converting to a string.
To get what you want, you would have to write your code as SET(COLUMN(price)"=hi")
.
You can't overload operator=()
for a built-in type. This is done for sanity maintenance, among other reasons.
C++ overloading is not intended to allow you to force the compiler to parse a different language.
P.S. Overloading operator=()
in the Table
class only handles the case where a Table
is on the left-hand side of the =
. That would require COLUMN(x)
to return a Table
object, probably not what you want. You could use an adaptor class to get this effect, but the syntax of COLUMN(x)
doesn't include which table this column is from, so you're stuck there too.
One way out there solution would look something like this:
class ColumnSetter
{public:
ColumnSetter(const char* name): name(name), value(0) {}
ColumnSetter& operator=(const char* value_) { value = value_; }
operator std::string const &() const { std::string result(name);
if(value) { result.append('='); result.append(value); } return result; }
private:
const char* name;
const char* value;
};
#define COLUMN(x) ColumnSetter(#x)
void callMe(const std::string& param);
Reformat and de-inline to whatever coding standards you have.
You mean like
#define SET(x) (CallMe(x))
ps - usual disclaimer about using the preprocessor
This should be done with classes that overload the various logical operators to create an abstract syntax tree instead of actually performing the operation. Then you can express various SQL expressions as C++ code and get an abstract syntax tree out which can then be serialized into an SQL WHERE
clause.
This isn't very hard, and if you are careful about it, it will be pretty efficient. It's much better than trying to use preprocessor hackery to create an SQL expression builder.
精彩评论