¿Cómo utilizar el atributo de formato printf de GCC con las plantillas variadic de C ++ 11?

Tengo una clase de C ++ que es la interfaz para un sistema de registro. Su función de registro se implementa utilizando las plantillas variadic de C ++ 11:

template <typename... Args>
void Frontend::log(const char *fmt, Args&&... args) {
  backend->true_log(fmt, std::forward<Args>(args)...);
}

Cada backend de logging implementa su propia versión detrue_log, que, entre otras cosas, utiliza los parámetros reenviados para llamarvsnprintf. P.ej.:

void Backend::true_log(const char *fmt, ...) {
  // other stuff..
  va_list ap;
  va_start(ap, fmt);
  vsnprintf(buffer, buffer_length, fmt, ap);
  va_end(ap);
  // other stuff..
}

Todo funciona muy bien, y estoy feliz.

Ahora, quiero agregar un control estático en ellog() parámetros: específicamente, me gustaría usar el atributo de formato printf de GCC.

Comencé etiquetando ellog() funcionar con__attribute__ ((format (printf, 2, 3))) (comothis es el primer parámetro "oculto", necesito cambiar los índices de parámetros en uno). Esto no funciona, porque si falla con un error de compilación:

error: args to be formatted is not ‘...’

Entonces, traté de agregar el mismo atributo a latrue_log() función. Se compila, pero no se realiza ninguna comprobación de errores: intenté pasar alog() algunas combinaciones de formato / variable no válidas, y no se emitió ninguna advertencia. Tal vez este tipo de verificación sea "demasiado tarde", o, en otras palabras, ¿la información sobre la variable se ha perdido en la cadena de llamadas?

Como último recurso, si he anotado.log() con__attribute__ ((format (printf, 2, 0))), Recibiría advertencias sobre cadenas de formato incorrectas, pero no se emitiría ningún diagnóstico para combinaciones de formato / variable no válidas.

Resumiendo el problema:¿Cómo puedo tener una verificación de formato completa de GCC si uso las plantillas variadic de C ++ 11?

Respuestas a la pregunta(2)

Su respuesta a la pregunta