C++ 函数使用可变模板包将std::string转换为const char*?

C++ 函数使用可变模板包将std::string转换为const char*?,c++,formatting,C++,Formatting,我使用的格式函数的灵感来自。只要我将const char*传递给它,一切正常: const char* hello = "Hello"; std::string world = "world"; string_format("%s, %s!", hello , world.c_str()); // Returns "Hello, world!" 现在,我在所有地方都使用std::strings,我希望避免在所有地方调用.c_str()。如何修改此函数以便为我调用它并允许我将std::str

我使用的格式函数的灵感来自。只要我将
const char*
传递给它,一切正常:

const char* hello = "Hello";
std::string world = "world";

string_format("%s, %s!", hello , world.c_str()); 
// Returns "Hello, world!"

现在,我在所有地方都使用std::strings,我希望避免在所有地方调用
.c_str()
。如何修改此函数以便为我调用它并允许我将std::strings传递给它?

您可以将
.c_str()
调用添加到模板函数内的参数包扩展中

template<typename ... StringArgs>
std::string
string_format(const std::string& format, StringArgs ... args)
{
    std::size_t size = std::snprintf(nullptr, 0, format.c_str(), args.c_str() ...) + 1;
                                                               //^^^^^^^^^^^^
    std::unique_ptr<char[]> buf(new char[size]);
    std::snprintf(buf.get(), size, format.c_str(), args.c_str() ...);
                                                 //^^^^^^^^^^^^
    return std::string(buf.get(), buf.get() + size - 1);
}

int main(void)
{
    std::string h{"hello"};
    std::string w{"world"};
    std::cout << string_format("%s %s\n", h, w) << std::endl; // This works
    // This won't compile
    // std::cout << string_format("%d\n", 0) << std::endl;
}
模板
字符串
string_格式(const std::string&format、StringArgs…args)
{
std::size\u t size=std::snprintf(nullptr,0,format.c_str(),args.c_str()…)+1;
//^^^^^^^^^^^^
std::unique_ptr buf(新字符[大小]);
snprintf(buf.get(),size,format.c_str(),args.c_str()…);
//^^^^^^^^^^^^
返回std::string(buf.get(),buf.get()+size-1);
}
内部主(空)
{
std::字符串h{“hello”};
std::字符串w{“world”};

std::cout我最终使用了一个中间函数
safe

#include <iostream>
#include <memory>
#include <iostream>
#include <string>
#include <cstdio>
#include <type_traits>


using namespace std;

template<typename T>
T safe(const T& value)
{return value;}

const char * safe(const string& value)
{return value.c_str();}


template<typename ... Args>
string string_format( const std::string& format, const Args& ... args )
{
    size_t size = snprintf( nullptr, 0, format.c_str(), safe(args)... ) + 1; // Extra space for '\0'
    unique_ptr<char[]> buf( new char[ size ] ); 
    snprintf( buf.get(), size, format.c_str(), safe(args)... );
    return string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
}


int main()
{
    cout<<string_format("%s, %s! %d", "hello", string("world"), 42);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
模板
T安全(常数T和值)
{返回值;}
常量字符*安全(常量字符串和值)
{返回值.c_str();}
模板
字符串字符串格式(常量标准::字符串和格式,常量参数和…参数)
{
size\u t size=snprintf(nullptr,0,format.c\u str(),safe(args)…)+1;//为'\0'预留额外空间
唯一的(新字符[大小]);
snprintf(buf.get(),size,format.c_str(),safe(args)…);
返回字符串(buf.get(),buf.get()+size-1);//我们不希望“\0”在里面
}
int main()
{

谢谢你,我从你的答案中找到了一个解决方案——看看我的