将任何类型转换为字符串的 Variadic 函数
Variadic Function that converts any type to string
我正在尝试在 C++ 中使用泛型和可变参数来创建一个方法,该方法接受任何可字符串类型并将其连接成单个字符串。
我正在寻找的功能示例是
stringify(50, 5000.00, "test") 结果应该是 "505000.00test".
您可以简单地使用 std::ostringstream 和 C++17 折叠表达式来做到这一点:
#include <sstream>
#include <iostream>
template <typename... Args>
std::string stringify(Args&&... args)
{
std::ostringstream str;
(str << ... << args);
return str.str();
}
这将能够将任何支持 operator <<
标准格式流输出的东西连接成 std::string
…
如果您希望能够在表达式 SFINAE 中调用此函数,您可以将签名修改为
template <typename... Args>
auto stringify(Args&&... args) -> decltype((std::declval<std::ostream>() << ... << args), std::declval<std::ostringstream>().str());
使用C++17 fold-expressions, to_string()
(in lieu of the heavier iostreams), and SFINAE:
#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));
}
将无处不在的流插入器实现的优势与 to_string()
的优势相结合,通常性能要好得多,它可以正常工作:
#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...);
}
我正在尝试在 C++ 中使用泛型和可变参数来创建一个方法,该方法接受任何可字符串类型并将其连接成单个字符串。
我正在寻找的功能示例是
stringify(50, 5000.00, "test") 结果应该是 "505000.00test".
您可以简单地使用 std::ostringstream 和 C++17 折叠表达式来做到这一点:
#include <sstream>
#include <iostream>
template <typename... Args>
std::string stringify(Args&&... args)
{
std::ostringstream str;
(str << ... << args);
return str.str();
}
这将能够将任何支持 operator <<
标准格式流输出的东西连接成 std::string
…
如果您希望能够在表达式 SFINAE 中调用此函数,您可以将签名修改为
template <typename... Args>
auto stringify(Args&&... args) -> decltype((std::declval<std::ostream>() << ... << args), std::declval<std::ostringstream>().str());
使用C++17 fold-expressions, to_string()
(in lieu of the heavier iostreams), and SFINAE:
#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));
}
将无处不在的流插入器实现的优势与 to_string()
的优势相结合,通常性能要好得多,它可以正常工作:
#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...);
}