I have a custom logger that uses a logger->logf(format, ...) style varargs method for logging. I have object handles that are wrappers around pointers. I have a special format specifier to print the objects ( with a toString() method like in Java)
The "handles" are not "trivially copyable" as they can be constructed from a number of input types, and have converter-cast operators that return the pointer to the contained object type. ( similar to ComPtr<> )
IN windows C++ I can just pass the handle in and the varags method sees the pointer. GCC considers this an error now. The handle is "sizeof(void *)"
Is there a way to get GCC to allow this on a varags method? Is there a way to specify a special operator xx () method to be passed into a varargs method?
I have a rather large library with a lot of log lines in it and redoing all of them with operator + or operator << would be an intense chore.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Well if does look like the Variadic template is what I need to use but I have yet to figure out how to make it simple an elegant.
The essence of an algorithm would be
place object or buffer on stack (ideally based on the number of arguments) add all the arguments to the object. on the last argument add it to the object, as well and process the arguments.
The "recursive" nature of a variadic template makes a nice way to do this a bit to figure out.
#Ok I bit the bullet and rewrote the formatter part to use variadic templates. It did take 3 days. Basically it involves having an "Arg" class that has a union of all the primitive types and a "type" field set by the constructor overload for each type.
Then a variadic template to "load a list" of args which is passed to the formatters equivalent of "vsprintf". Great as there is enough information to be runtime type safe. The quastion now is HOW much code bloat is there with the template expansion. As all they do is cast and the "Arg" is a fixed size and it's constructor just loads two fields, type and value. Will GCC and MSC nicely optimize all of it out so there aren't 2 ^ maxArgs full expansions of the variadic templates.
template <typename... Args>
int writef(const wchar_t *fmt, ...) {
FormatfArglist<sizeof...(Args)> arglist;
FormatfArgBase::addArgs(arglist.args(), args...);
return(vwritef(fmt, arglist));
}
template <typename First, typename... Rest>
static void FormatfArgBase::addArgs(Arg *arglist,
const First &first, const Rest &... rest) {
setArg(arglist,Arg(first));
if(sizeof... (Rest) > 0) {
addArgs(++arglist, rest...); // recursive call using pack expansion syntax
}
}