Il problema è di implementazione. Diciamo che era possibile. Poi std::function
avrebbe dichiarare (nel caso di printf)
int operator()(char* fmt, ...)
Quando viene chiamato, avrebbe poi dovuto passare il contenuto della ... a qualsiasi oggetto che è stato assegnato. Il problema è che non conosce abbastanza gli argomenti per sapere COME passarlo, che è un problema. printf() analizza il formato, ma altri usano altri meccanismi (un valore 'end' è popolare).
Per la famiglia di funzioni printf, suggerisco di guardare le versioni vXXX (ad esempio vprintf). Poiché utilizzano argomenti ben definiti (l'ultimo è l'elenco di argomenti variabili), sarebbe possibile associare std::function
a quelle versioni.
Edit:
Cosa si può fare, però, è scrivere il proprio involucro che utilizza le funzioni vprintf
, e gestisce la vararg-> di conversione va_list.
#include <cstdio>
#include <cstdarg>
#include <functional>
class PrintWrapper
{
public:
PrintWrapper() = default;
template<typename T>
PrintWrapper(T&& t) : func(std::forward<T>(t))
{
}
int operator()(char const* format, ...)
{
va_list args;
va_start(args, format);
int result = func(format, args);
va_end(args);
return result;
}
private:
std::function< int(char const*, va_list)> func;
};
int main()
{
// Note, you have to use the 'v' versions
PrintWrapper p = std::vprintf;
p("%d %d %s\n", 1,2, "hello");
char buffer[256];
using namespace std::placeholders;
p = std::bind(std::vsnprintf, buffer, sizeof(buffer), _1, _2);
p("%lf %s\n", 0.1234, "goodbye");
// Since the previous step was a wrapper around snprintf, we need to print
// the buffer it wrote into
printf("%s\n", buffer);
return 0;
}
http://ideone.com/Sc95ch
fonte
2013-08-22 01:55:12
Potrei scrivere una classe equivalente a 'std :: function' in C++ 11: come è,' std :: function' può essere scritta come una classe file di intestazione puro un modo conforme standard. Non sono sicuro di poter scrivere 'std :: function' senza estendere la lingua o usando estensioni specifiche del compilatore. Possiamo avere metodi variardici 'virtuali' in stile C? E anche in questo caso, l'oggetto di cancellazione di tipo interno dovrebbe quindi inoltrare gli argomenti '...' a 'printf', che non è supportato AFAIK. –
Yakk
@Yakk: FYI, puoi avere un metodo varadico in stile C 'virtuale'. Il problema è che non è possibile passare i parametri varadici in stile C a un'altra funzione senza convertirli in una va_list o analizzarli da soli. –