首页 > 解决方案 > 如何在 C++ 11 中使用可变参数模板在不递归的情况下形成字符串

问题描述

template <typename ...Args>
void logImpl(tloglevel level, Args&& ...args)
{
    ostringstream stream;
    (stream << ... << std::forward<Args>(args)) << '\n';
    syslog(level, stream.str());
}

func A()
{
int a =10;
std::string b = "test";
logImpl(LOG_INFO, "printing",a,b);
}

func B()
{
unsigned long t = 6700;
logImpl(LOG_INFO, t);
}

我知道我们可以使用可变参数模板来实现它。但是没有递归就可以做到吗?fold 表达式不是一个选项,因为仅支持 c++ 11。请让我知道是否有其他人有更好的想法使用没有递归或折叠表达式的可变参数模板。我想用 c++11 来做。

标签: c++11variadic-templates

解决方案


您不需要使用递归来完成这项工作。

您可以在填充时使用扩展参数包创建假数组:

template<class ... Args>
std::string makeString(Args...args){
    std::string s;
    int temp[] = { (s += toString(args),0)... }; // concatenation
    static_cast<void>(temp);
    return s;
}

因为toString您提供重载来处理您想要的所有类型。

例如:

template<class T>
std::string toString(T t){
    return std::to_string(t);   // for numbers 
}

std::string toString(const std::string& str){
    return str;
}

std::string toString(const char* str){
    return str;
}

完整演示


嗯,你甚至不使用toString, 版本ostringstream是:

template<class ... Args>
std::string makeString(Args&&...args){
    std::ostringstream os;
    int temp[] = { ((os << std::forward<Args>(args)),0)... };
    static_cast<void>(temp);
    return os.str();
}

推荐阅读