例如,这无法编译:
std::function<decltype(printf)> my_printf(printf);
使用gcc,错误消息显示为:
error: variable 'std::function<int(const char*, ...)> my_printf' has initializer but incomplete type
std::function<decltype(printf)> my_printf(printf);
Run Code Online (Sandbox Code Playgroud)
起初我以为这是gcc中的一个错误,但后来我看了标准,看起来这样就不支持了.这是什么技术原因?
问题是实施之一.让我们说这是可能的.然后std::function必须声明(在printf的情况下)
int operator()(char* fmt, ...)
调用时,它必须将...的内容传递给您指定的任何对象.问题在于它不知道如何知道如何将其传递下来,这是一个问题.printf()解析格式,但其他人使用其他机制('end'值很受欢迎).
对于printf系列函数,我建议你看一下vXXX版本(例如vprintf).由于它们使用定义良好的参数(最后一个是变量参数列表),因此可以绑定std::function到这些版本.
编辑:
但是,您可以编写自己的使用vprintf函数的包装器,并处理vararg-> 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;
}
Run Code Online (Sandbox Code Playgroud)