C ++-vsprintf_s和std :: string?

时间:2019-03-07 09:54:43

标签: c++ stdstring

我有一个使用'...'参数的日志记录功能,并使用vsprintf_s创建最终输出字符串

除了我总是必须使用c_str()来打印字符串

之外,它都可以正常工作

起初我以为这不是问题,但是在每个字符串变量之后添加所有这些 .c_str()却很痛苦,而我却一直忘记它们

尽管我可能是C ++专家可以启发我解决这个问题,但是有没有办法让我的日志记录功能自己来解决这个问题?

void Logger::print(const std::string fmt, ...)
{
    va_list args;
    int len;
    char * buffer;
    va_start(args, fmt);
    len = _vscprintf(fmt.c_str(), args)+1;
    buffer = (char*)malloc(len * sizeof(char));
    vsprintf_s(buffer, len, fmt.c_str(), args);
    va_end(args);
    std::cout << buffer << std::endl; 
    free(buffer);
}

谢谢

1 个答案:

答案 0 :(得分:0)

您可以添加两个可变参数包装函数模板,如下所示:

#include <type_traits>

template <class Arg>
decltype(auto) prepare(const Arg& arg)
{
   if constexpr (std::is_same_v<Arg, std::string>)
      return arg.c_str();
   else
      return arg;
}

template <class ...Args>
void printWrapper(Args&&... args)
{
   Log::print(prepare(std::forward<Args>(args))...);
}

并调用printWrapper而不是原始成员函数。请注意,这里我假设Log::print是静态成员函数。如果不是这种情况,则需要对其进行调整。现在应该可以使用:

const std::string hello("hello");

printWrapper("%d %s %s", 42, hello, "world");

请注意,要进行此编译,必须使用C ++ 17。