C++ 将任何类型转换为字符串的变量函数

C++ 将任何类型转换为字符串的变量函数,c++,string,variadic-functions,C++,String,Variadic Functions,我尝试使用C++中的泛型和ValARGS来生成一种方法,它接受任何可伸缩类型并将其串接成一个字符串。 我正在寻找的一个功能示例是 stringify(505000.00,“test”),结果应该是“505000.00test”。您只需使用一个和一个C++17倍的表达式即可: #include <sstream> #include <iostream> template <typename... Args> std::string stringify(Args

我尝试使用C++中的泛型和ValARGS来生成一种方法,它接受任何可伸缩类型并将其串接成一个字符串。 我正在寻找的一个功能示例是

stringify(505000.00,“test”),结果应该是“505000.00test”。

您只需使用一个和一个C++17倍的表达式即可:

#include <sstream>
#include <iostream>

template <typename... Args>
std::string stringify(Args&&... args)
{
    std::ostringstream str;
    (str << ... << args);
    return str.str();
}
使用(代替较重的流),以及:


你想用什么机制来串接单个组件?你想用c++17吗?很遗憾,我不能用c++17。我没有偏好,但它需要能够支持多种类型。此外,这将被称为许多次,需要尽快,因为它可以!您不支持SFINAE,而且
std::ostringstream
非常重要。另一方面,许多自定义类型都支持流插入。@重复数据消除,或者如果您觉得这里确实需要SFINAE支持,那么当然可以添加它。我在上面的回答中补充了一句如何做到这一点的话。如果问题是将任意内容转换为字符串,那么我们希望不要从性能关键领域开始讨论。我认为OP很可能会寻找一个通用的解决方案而不是担心性能。而且,正如您自己所指出的,上面的简单方法能够利用针对给定类型可能存在的格式化输出的任何标准设施……关于性能,请注意,
std::to_string
必须遵守当前区域设置,因此它也不一定是最有效的方法。在我的机器上进行的快速测试中,它比std::ostringstream快2倍左右。但是,
std::to_string
只能处理算术类型。您必须自己添加重载以支持其他类型。它也不支持任何格式选项。这是一个值得考虑的权衡。如果您这样做,请注意简洁的函数模板语法不是C++17,并且尾部返回类型将需要包装在一对额外的
()
…@MichaelKenzel修复了这一问题,并添加了更复杂的代码,以使用可能最有效的解决方案。这是一个很好的答案!不幸的是,我现在还不能使用c++17,但我会接受这一点,因为将来可能需要类似的东西。
template <typename... Args>
auto stringify(Args&&... args) -> decltype((std::declval<std::ostream>() << ... << args), std::declval<std::ostringstream>().str());
#include <string>
#include <utility>

using std::to_string;
auto to_string(std::string s) noexcept { return std::move(s); }

template <class... T>
auto stringify(T&&... x)
-> decltype((std::string() + ... + to_string(x))) {
    return (std::string() + ... + to_string(x));
}
#include <string>
#include <utility>
#include <sstream>

namespace detail {
    using std::to_string;
    auto to_string(std::string s) noexcept { return std::move(s); }

    template <class... T>
    auto stringify(int, T&&... x)
    -> decltype((std::string() + ... + to_string(x))) {
        return (std::string() + ... + to_string(x));
    }

    template <class... T>
    auto stringify(long, T&&... x)
    -> decltype((std::declval<std::ostream&>() << ... << x), std::string()) {
        std::stringstream ss;
        (ss << ... << x);
        return ss.str();
    }
}

template <class... T>
auto stringify(T&&... x)
-> decltype(detail::stringify(1, x...)) {
    return detail::stringify(1, x...);
}