Construção literal de cadeia de caracteres de formato de tempo de compilação C ++ 11 para chamar printf
O que eu gostaria de fazer é criar:
template<Args... args)>
int println(Args...) {
// implementation which calls:
// printf("<string literal format string at compile time>", args...);
// additional perk would be compile time type checking
// I expect to provide a format string for each type by some template
// specialization.
}
Eu tenho analisado duas peças interessantes de trabalho com literais de string de tempo de compilação:
Literais de seqüência de caracteres alinhados com memória de tempo de compilação
https://stackoverflow.com/a/22067775/403571
100% de implementação de cadeia de caracteres constexpr
http://sourceforge.net/p/constexprstr/code/HEAD/tree/no-pp-constexpr_string.cpp
Basicamente, sou mais ou menos capaz de inferir estaticamente o comprimento da literal de string necessária para o formato, mas nada mais que o compilador se recusa a tratar meu trabalho como constexpr. Outro grande problema é que, ao usar seqüências constexpr no link acima, o compilador nunca consegue inferir o tamanho da sequência resultante.
Quanto mais eu tento conseguir isso, mais minha ignorância supera meu entusiasmo. Eu gostaria de receber dicas e / ou exemplos de código que resolvam alguns ou todos os problemas ao fazer essa implementação.
Nota: Não estou procurando conselhos sobre o uso de diferentes formas de registro, como através do cout.
Nota2: O não deve usar nenhum std :: string, pois esses são em tempo de execução
Nota 3: Geralmente, todos os printfs com segurança de tipo estão usando abordagens diferentes, e eu sei que isso pode ser feito facilmente com várias chamadas paraprintf
. Eu gostaria de fazer isso em uma única ligação. Eu também sei que o buffer pode ser incrementalmente construído, mas esta pergunta é sobre a construção da string de formato. :)
Atualização: Basicamente, o que parte do código precisa alcançar é
constexpr const char* formatString = build_compile_time_format_string(args...);
// build_compile_time_format_string(3, "hi", -3.4)
// should evaluate to "%d %s %f"
// or to "%d hi %f"