如何在 C++ 11 中使用不递归的可变参数模板形成字符串

How to form a string using variadic templates without recursion in 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);
}

我知道我们可以使用可变参数模板来实现它。但是有没有可能不用递归呢?折叠表达式不是一个选项,因为仅支持 c++ 11。如果其他人对使用不带递归或折叠表达式的可变参数模板有更好的想法,请告诉我。我想用 c++11 来做。

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

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

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;
}

Full demo


嗯,你甚至不使用 toStringostringstream 的版本是:

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();
}