Is it a good style about boost::format( format-string ) % arg1 % arg2 % ... % argN
Hi, First, I am a new user of boost. I wonder of the style of 'boost::format( format-string ) % arg1 % arg2 % ... % argN'. I think it, format(...), as a function, but it seems not function in C or C++ style. % arg1 % ... seems like a group of parameters, if so, why not use '(' and ')' to wrap them? As it works, there must be something I don't know. Please feel free to point out what I am wrong. I'm very glade to know them. Thanks! -- Sincerely yours, William
On 10/11/06, William Xue
First, I am a new user of boost. I wonder of the style of 'boost::format( format-string ) % arg1 % arg2 % ... % argN'. I think it, format(...), as a function, but it seems not function in C or C++ style.
variable arguments are very nasty in C++. Not only that, but the va_* macros do not allow for type safe generic programming (or type safety in general). The way it works is that boost::format("..."); returns an object which has the % operator defined. object % <anything> performs the operation and returns the same object. This allows for chaining. I'd assume the goal is to mirror python syntax. The problem with something like this: boost::format("...") % (a,b,c,d); is that C++ does not allow it. It is not syntactically correct.
On Thu, 12 Oct 2006 03:20:33 +0800, Aaron Griffin
On 10/11/06, William Xue
wrote: First, I am a new user of boost. I wonder of the style of 'boost::format( format-string ) % arg1 % arg2 % ... % argN'. I think it, format(...), as a function, but it seems not function in C or C++ style.
variable arguments are very nasty in C++. Not only that, but the va_* macros do not allow for type safe generic programming (or type safety in general).
The way it works is that boost::format("..."); returns an object which has the % operator defined. object % <anything> performs the operation and returns the same object. This allows for chaining.
Thank you very much! Your explanation is very clear. I am agree with you, it's nasty. As someone had said, the style smelt very bad. Though C/C++ is very flexible, I do not like to broke the regular rules of them. Micrisoft have done something like this in their sample codes: ---8<--------------------------------------------->8--- #define PURE =0 ... interface xxx { ... int foo(...) PURE; ... }; ---8<--------------------------------------------->8--- I can not to find out any wisdom in doing things like this. As a C/C++ user, I am very glad to see someone to extend the features of them, But IMHO, C/C++ is C/C++, do not go far away from the regular way. Again, thanks.
I'd assume the goal is to mirror python syntax.
The problem with something like this: boost::format("...") % (a,b,c,d); is that C++ does not allow it. It is not syntactically correct. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sincerely yours, William
William Xue wrote:
Thank you very much! Your explanation is very clear. I am agree with you, it's nasty.
He said variable arguments were nasty. This is not the case of this type-safe chaining. From what you're saying, it seems you understood it the other way around. Excuse me if I am the one who understood you wrong.
Though C/C++ is very flexible, I do not like to broke the regular rules of them.
C and C++ are different languages. Variable arguments, a feature from C, has a lot of problems and shouldn't be used at all in C++ since you can build better alternatives. Using that kind of chaining is not "breaking the regular rules". It's an usage of the generic paradigm from C++, which is what makes boost what it is.
Micrisoft have done something like this in their sample codes: ---8<--------------------------------------------->8--- #define PURE =0 ... interface xxx { ... int foo(...) PURE; ... }; ---8<--------------------------------------------->8---
I can not to find out any wisdom in doing things like this.
Usually you don't use the define PURE or a fake interface keyword, but it is a very usual concept : it's an abstract base class. It's only used in polymorphic designs though, which are unrelated to boost.format.
As a C/C++ user, I am very glad to see someone to extend the features of them, But IMHO, C/C++ is C/C++, do not go far away from the regular way.
C/C++ is nothing. It is a term usually used by people who code C++ using C techniques. There is C, and there is C++. Each one has its way of doing things. C not having the features from C++, the C way is probably more dangerous and less flexible. The C way is to use variable arguments, which aren't type safe (which probably leads to tons of problems) and only work for PODs. The C++ way could be to use variadic templates, which aren't in the standard yet, or to use operator overloading and do chaining (just like the standard iostreams). And also, if we didn't use a few tricks you may consider "not the regular way", generic programming in C++ and therefore boost itself would be very limited.
Thanks for your reply.
On Fri, 13 Oct 2006 01:03:33 +0800, loufoque
William Xue wrote:
Thank you very much! Your explanation is very clear. I am agree with you, it's nasty.
He said variable arguments were nasty. This is not the case of this type-safe chaining.
Maybe, But I think what we talked about is 'boost::format( format-string ) % arg1 % arg2 % ... % argN', And 'Not only that, but the ...'.
From what you're saying, it seems you understood it the other way around. Excuse me if I am the one who understood you wrong.
Though C/C++ is very flexible, I do not like to broke the regular rules of them.
C and C++ are different languages. Variable arguments, a feature from C, has a lot of problems and shouldn't be used at all in C++ since you can build better alternatives.
Using that kind of chaining is not "breaking the regular rules". It's an
I agreed with "a chain is not 'breaking the regular rules'". But use a chain as a argument of a function (maybe not on syntactical, but it is on using), AND the argument what is out of the function's argument declaration list, this is 'breaking the regular rules'.
usage of the generic paradigm from C++, which is what makes boost what it is.
C++ is powerful, another example, gun is also. We can use it in this way, use it in that way, But we should always use it in a right way. Just a figure of speech.
Micrisoft have done something like this in their sample codes: ---8<--------------------------------------------->8--- #define PURE =0 ... interface xxx { ... int foo(...) PURE; ... }; ---8<--------------------------------------------->8---
I can not to find out any wisdom in doing things like this.
Usually you don't use the define PURE or a fake interface keyword, but it is a very usual concept : it's an abstract base class. It's only used in polymorphic designs though, which are unrelated to boost.format.
It's just a example. Could you tell me why they use a macro to declare a abstract base class, instead of dircetly using '=0' ? I don't conceal what I have thought, they define the macro is only for design, overengineering, Just like "format" here. For, if I did not know this MACRO, it's hard to understand what's the meaning of 'int foo(...) PURE;', but it's very clear of 'int foo(...) = 0;', even if I am a beginner of C++, isn't it? PURE is only one of examples in codes of, as you said, polymorphic design. It's hard to understand, hard to study those technologies when there are a large number of these MACROs, essentially, they can be a little easier. Well, this is another topic.
As a C/C++ user, I am very glad to see someone to extend the features of them, But IMHO, C/C++ is C/C++, do not go far away from the regular way.
C/C++ is nothing. It is a term usually used by people who code C++ using C techniques.
Maybe I really mis-understood something, I always use C/C++ as C and C++, or C or C++.
There is C, and there is C++. Each one has its way of doing things. C not having the features from C++, the C way is probably more dangerous and less flexible.
I should say something about this. I never thought any language is really 'dangerous', maybe you means libraries for C? IMHO, Only carelessness is dangerous. Of cause, a type safe or a strict type checking language is much easy to get safe.
The C way is to use variable arguments, which aren't type safe (which probably leads to tons of problems) and only work for PODs. The C++ way could be to use variadic templates, which aren't in the standard yet, or to use operator overloading and do chaining (just like the standard iostreams).
And also, if we didn't use a few tricks you may consider "not the regular way", generic programming in C++ and therefore boost itself would be very limited.
IMHO, Whatever you used in internal implemention, the "INTERFACE" should be kept simple and easy (in the regular way) to read for any user of C++, Especially for beginners like me.:)
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sincerely yours, William
On 10/12/06, William Xue
It's just a example. Could you tell me why they use a macro to declare a abstract base class, instead of dircetly using '=0' ? I don't conceal what I have thought, they define the macro is only for design, overengineering, Just like "format" here.
For, if I did not know this MACRO, it's hard to understand what's the meaning of 'int foo(...) PURE;', but it's very clear of 'int foo(...) = 0;', even if I am a beginner of C++, isn't it?
PURE is only one of examples in codes of, as you said, polymorphic design. It's hard to understand, hard to study those technologies when there are a large number of these MACROs, essentially, they can be a little easier.
Well, this is another topic.
IIR/UC, MS used PURE because the code actually compiled in both C and C++. Under C++ it became '=0', but under C it was empty (I think). Basically, you often saw this in interface definitions for COM objects, which, under C, compiled into a struct of function pointers, and under C++ as a pure interface class (and in memory, looked the same either way). Tony
On Fri, 13 Oct 2006 11:40:49 +0800, Gottlob Frege
IIR/UC, MS used PURE because the code actually compiled in both C and C++. Under C++ it became '=0', but under C it was empty (I think). Basically, you often saw this in interface definitions for COM objects, which, under C, compiled into a struct of function pointers, and under C++ as a pure interface class (and in memory, looked the same either way).
Tony
Yes, it's a good explanation. Thanks a lot. For the reason I mentioned above, I perfer to do the job like this: ---8<--------------------------------------------->8--- #ifdef cplusplus class ... { ... int foo(...) = 0; ... }; #else class ... { ... int foo(...); ... }; #endif ---8<--------------------------------------------->8--- OK, it's just a example for something of this thread.;) -- Sincerely yours, William
On 10/11/06, William Xue
First, I am a new user of boost. I wonder of the style of 'boost::format( format-string ) % arg1 % arg2 % ... % argN'. I think it, format(...), as a function, but it seems not function in C or C++ style.
You are right. There is a much better implementation, Loki::Printf in SafeFormat.h. It works like this: Printf("1 + 1 = %d\n")(2); -> 1 + 1 = 2 Printf("The address of %s is 0x%08lX.\n")("Var")(dwAddr); -> The address of Var is 0x004B256A. Each operator() returns a PrintState class object, and can be operated chainly. Also, Loki gives us a complete printf-like functions, SPrintf, FPrintf... It really convenient. Compared to Loki::Printf, the boost::format is not so good. I think its motivation is ambiguous. Actually, users want a "type-safe printf", not a "iostream with new format rules". To use boost::format, I have to study a lot for its gramma which makes my code un-readable to other people who do not know boost::format. (Please forgive me the author of boost::format. ^_^) ShenLei
On Behalf Of ShenLei You are right. There is a much better implementation, Loki::Printf in SafeFormat.h. It works like this: // ...
Also, Loki gives us a complete printf-like functions, SPrintf, FPrintf... It really convenient.
Yes, they are convenient, but Loki::Printf and crew have a serious shortcoming -- lack of support for wide characters. As with std::exception, this greatly reduces their utility. This is the main reason why I prefer boost::format. Regards, Ryan Ginstrom
After I used it a bit (2 days?) I got pretty used to it. I've been working on a embedded system for several years, with no debugger, only printf, so I'm fairly used to that... but after a little practice I'm really starting to like the boost::format.
participants (7)
-
Aaron Griffin
-
Andrew Schweitzer
-
Gottlob Frege
-
loufoque
-
Ryan Ginstrom
-
ShenLei
-
William Xue