文章目录
一、简介
这里使用std标准库简单实现一个字符格式化输出,方便后续的使用,它有点类似Qt中的QString操作。
二、实现代码
FMTString.hpp
cpp
#pragma once
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <optional>
#include <random>
#include <type_traits>
#include <sstream>
namespace FMT
{
void formatStream(std::stringstream& stream, char const* text) {
stream << text;
return;
}
/// <summary>
/// 在编译时检测某个类型T是否支持通过 operator<< 输出到流(如std::stringstream)
/// </summary>
/// <typeparam name="T"></typeparam>
template <class T>
class IsStreamable {
private:
template <class TT>
static auto test(int)
-> decltype(std::declval<std::stringstream&>() << std::declval<TT>(),
std::true_type());
template <class>
static auto test(...)->std::false_type;
public:
static bool const value = decltype(test<T>(0))::value;
};
/// <summary>
/// 将任意类型的参数通过流操作符 << 转换为字符串流(std::stringstream)的内容
/// </summary>
/// <typeparam name="T"></typeparam>
template <class T>
class ArgToStream {
public:
static void impl(std::stringstream& stream, T&& arg) {
stream << std::forward<T>(arg);
}
};
/// <summary>
/// 将格式字符串 text 中的 {} 占位符依次替换为传入的参数 arg, args...,并将结果写入 std::stringstream 流中
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="...Args"></typeparam>
/// <param name="stream"></param>
/// <param name="text"></param>
/// <param name="arg"></param>
/// <param name="...args"></param>
template <class T, typename... Args>
void formatStream(std::stringstream& stream, char const* text, T&& arg,
Args&&... args) {
static_assert(IsStreamable<T>::value,
"One of the args has no ostream overload!");
for (; *text != '\0'; ++text) {
if (*text == '{' && *(text + 1) == '}') {
ArgToStream<T&&>::impl(stream, std::forward<T>(arg));
formatStream(stream, text + 2, std::forward<Args>(args)...);
return;
}
stream << *text;
}
stream << "\nFormat-Warning: There are " << sizeof...(Args) + 1
<< " args unused.";
return;
}
template <class... Args>
std::string formatString(char const* text, Args&&... args) {
std::stringstream stream;
formatStream(stream, text, std::forward<Args>(args)...);
return stream.str();
}
}
main.cpp
cpp
// 标准文件
#include <iostream>
#include <string>
#include "FMTString.hpp"
int main(int, char** argv)
{
std::string msg = FMT::formatString("Hello, {}! You have {} new messages.", "Alice", 5);
std::cout << "Output:" << msg << std::endl;
system("pause");
return 0;
}
三、实现效果
