|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
hi
our internal log apis support varargs, but do not support <<, it means that we have to write funciton tracing like this: printf("%s(%d,%f)", functionName,iCount,dTime); this need us write format string mannualy each time. I think the better style looks like: #define BetterFunctionTrace .... BetterFunctionTrace(functioName, iCount,dTime); Is there any way to generate the format string in the compile time accroding to parameter type and parameter number? i.e. function1(int,char*,double) => %s(%d,%s,%f); function2(int,char*,double,unsigned int) => %s(%d,%s,%f,%u); any idea? thanks |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Oct 16, 1:24 am, baibaichen <baibaic...@gmail.com> wrote:
> Is there any way to generate the format string in the compile time > accroding to parameter type and parameter number? i.e. > > function1(int,char*,double) => %s(%d,%s,%f); > function2(int,char*,double,unsigned int) => %s(%d,%s,%f,%u); Part of the reason printf() and family use format strings is because it's impossible to tell the number of arguments passed to a vararg function, nor even the type of the next argument coming up. So basically, you'd need to use a format string or some similar way of passing information as a first parameter if your vararg list can change a lot. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Is this something you can use?
#include <iostream> #include <string> template <class T> struct ToString; // keep this empty to emit a compile time error // when it doesn't have a associated string // Define the format specifiers of the basic types #define DEF0TYPE( type, str ) \ template <> \ struct ToString< type > \ { static std::string value() { return str; } \ }; DEF0TYPE( int, "%d" ) DEF0TYPE( double, "%f" ) DEF0TYPE( char *, "%s" ) DEF0TYPE( const char *, "%s" ) DEF0TYPE( float, "%f") DEF0TYPE( char, "%c") /* andsoforth... */ #undef DEF0TYPE // define the format string of a nullary function template <class Return> struct ToString< Return (*) () > { static std::string value() { return "%s()"; } }; // unary functions template <class Return, class T > struct ToString< Return (*) ( T ) > { static std::string value() { return std::string("%s(") + ToString<T> :: value() + ")"; } }; // binary functions template <class Return, class T, class U > struct ToString< Return (*) ( T , U ) > { static std::string value() { return std::string("%s(") + ToString<T> :: value() + ", " + ToString<U>::value() + ")"; } }; // ternary functions template <class Return, class T, class U, class V > struct ToString< Return (*) ( T , U, V ) > { static std::string value() { return std::string("%s(") + ToString<T> :: value() + ", " + ToString<U>::value() + ", " + ToString<V>::value() + ")"; } }; // and so on // a er function, which provides a bit nicer syntax template <class T> std::string toString( T ) { return ToString<T> :: value(); } // two functions void function1( int a, double b) {} void function2( double x, double y, char * string) {} int main() { std::cout << "format string for the main function: " << toString( main ) << std::endl; std::cout << "format string of 'function1' " << toString( function1 ) << std::endl; std::cout << "format stirng of 'function2' " << toString( function2) << std::endl; return 0; } This gives as output format string for the main function: %s() format string of 'function1' %s(%d, %f) format stirng of 'function2' %s(%f, %f, %s) regard, Wijnand Suijlen |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Well that's perfect,
Hi wijnand, sorry if i am using your name? I know bits and peace about template programming, if you don't mind can you give some advice like which book to read for good template programming. It would be very ful if you can give link to any of the articles authored by you. On Oct 16, 7:31 pm, wijnand <wijnandsuij...@gmail.com> wrote: > Is this something you can use? > > #include <iostream> > #include <string> > > template <class T> > struct ToString; > // keep this empty to emit a compile time error > // when it doesn't have a associated string > > // Define the format specifiers of the basic types > #define DEF0TYPE( type, str ) \ > template <> \ > struct ToString< type > \ > { static std::string value() { return str; } \ > }; > > DEF0TYPE( int, "%d" ) > DEF0TYPE( double, "%f" ) > DEF0TYPE( char *, "%s" ) > DEF0TYPE( const char *, "%s" ) > DEF0TYPE( float, "%f") > DEF0TYPE( char, "%c") > /* andsoforth... */ > #undef DEF0TYPE > > // define the format string of a nullary function > template <class Return> > struct ToString< Return (*) () > > { > static std::string value() { return "%s()"; } > > }; > > // unary functions > template <class Return, class T > > struct ToString< Return (*) ( T ) > > { > static std::string value() { return std::string("%s(") + > ToString<T> :: value() + ")"; } > > }; > > // binary functions > template <class Return, class T, class U > > struct ToString< Return (*) ( T , U ) > > { > static std::string value() { return std::string("%s(") + > ToString<T> :: value() + ", " + ToString<U>::value() + ")"; } > > }; > > // ternary functions > template <class Return, class T, class U, class V > > struct ToString< Return (*) ( T , U, V ) > > { > static std::string value() { return std::string("%s(") + > ToString<T> :: value() + ", " + ToString<U>::value() + ", " + > ToString<V>::value() + ")"; } > > }; > > // and so on > > // a er function, which provides a bit nicer syntax > template <class T> > std::string toString( T ) > { > return ToString<T> :: value(); > > } > > // two functions > void function1( int a, double b) {} > void function2( double x, double y, char * string) {} > > int main() > { > std::cout << "format string for the main function: " << > toString( main ) << std::endl; > std::cout << "format string of 'function1' " << > toString( function1 ) << std::endl; > std::cout << "format stirng of 'function2' " << toString( function2) > << std::endl; > return 0; > > } > > This gives as output > format string for the main function: %s() > format string of 'function1' %s(%d, %f) > format stirng of 'function2' %s(%f, %f, %s) > > regard, > Wijnand Suijlen |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
raghukumar wrote:
> Well that's perfect, Please don't top-post. Your replies belong following or interspersed with properly trimmed quotes. See the majority of other posts in the newsgroup, or the group FAQ list: <http://www.parashift.com/c++-faq-lite/how-to-post.html> |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Hi Raghukumar,
On Oct 16, 5:15 pm, raghukumar <raghukumar.r...@gmail.com> wrote: > I know bits and peace about template programming, if you don't mind > can you give some advice like which book to read for good template > programming. I learned it from: C++ Template Metaprogramming by David Abrahams and Aleksey Gurtovoy which is a book in the C++ In-Depth Series ISBN:0-321-22725-5 Because C++ TMP is like functional programming, I had much from past experience in Haskell. This language I learned from the book: The Haskell School of Expression by Paul Hudak ISBN: 0-521-64408-9 > It would be very ful if you can > give link to any of the articles authored by you. I haven't written anything about this (yet ;-) ) Happy Meta-programming! Wijnand Suijlen |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Thanks, it does me
However getting such format string is also in run time not in complie time. -Chang |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Oct 16, 10:31 pm, wijnand <wijnandsuij...@gmail.com> wrote:
> Is this something you can use? > > #include <iostream> > #include <string> > > template <class T> > struct ToString; > // keep this empty to emit a compile time error > // when it doesn't have a associated string > > // Define the format specifiers of the basic types > #define DEF0TYPE( type, str ) \ > template <> \ > struct ToString< type > \ > { static std::string value() { return str; } \ > }; > > DEF0TYPE( int, "%d" ) > DEF0TYPE( double, "%f" ) > DEF0TYPE( char *, "%s" ) > DEF0TYPE( const char *, "%s" ) > DEF0TYPE( float, "%f") > DEF0TYPE( char, "%c") > /* andsoforth... */ > #undef DEF0TYPE > > // define the format string of a nullary function > template <class Return> > struct ToString< Return (*) () > > { > static std::string value() { return "%s()"; } > > }; > > // unary functions > template <class Return, class T > > struct ToString< Return (*) ( T ) > > { > static std::string value() { return std::string("%s(") + > ToString<T> :: value() + ")"; } > > }; > > // binary functions > template <class Return, class T, class U > > struct ToString< Return (*) ( T , U ) > > { > static std::string value() { return std::string("%s(") + > ToString<T> :: value() + ", " + ToString<U>::value() + ")"; } > > }; > > // ternary functions > template <class Return, class T, class U, class V > > struct ToString< Return (*) ( T , U, V ) > > { > static std::string value() { return std::string("%s(") + > ToString<T> :: value() + ", " + ToString<U>::value() + ", " + > ToString<V>::value() + ")"; } > > }; > > // and so on > > // a er function, which provides a bit nicer syntax > template <class T> > std::string toString( T ) > { > return ToString<T> :: value(); > > } > > // two functions > void function1( int a, double b) {} > void function2( double x, double y, char * string) {} > > int main() > { > std::cout << "format string for the main function: " << > toString( main ) << std::endl; > std::cout << "format string of 'function1' " << > toString( function1 ) << std::endl; > std::cout << "format stirng of 'function2' " << toString( function2) > << std::endl; > return 0; > > } > > This gives as output > format string for the main function: %s() > format string of 'function1' %s(%d, %f) > format stirng of 'function2' %s(%f, %f, %s) > > regard, > Wijnand Suijlen Thanks, it does me. but it's in run-time, not compile time. Is there any imporvement? chang |
|
![]() |
| Outils de la discussion | |
|
|