提供支持C++字符格式的printf函数
虽然C++中提供了iostream进行字符串格式化输出,但日常开发中还是多有不便,比如log的输出,一般还是采用printf格式化输出,但printf不支持C++的std::string, 使用时需要频繁的转换,因此实现了C++字符串自动识别的format函数。
使用示例:
class TestPrint
{
public:
TestPrint()
{
std::cout << "TestPrint 构造函数" << std::endl;
}
~TestPrint()
{
std::cout << "TestPrint 析构函数" << std::endl;
}
friend void operator << (std::iostream& out, const TestPrint& t)
{
out << t.val << "_" << t.a ;
}
private:
int a = 100;
std::string val = "hello";
};
int main()
{
std::string strMsg("my msg");
std::cout << format("this is %s --> %s", strMsg, TestPrint()) << std::endl;
}
输出:
TestPrint 构造函数
TestPrint 析构函数
TestPrint 析构函数
this is my msg --> hello_100
TestPrint 析构函数
实现过程:

头文件
//获取数据
template <typename T>
T DataTraits(T val)
{
return val;
}
//特化
const char* DataTraits(const std::string& ref);
//类型萃取,对非基础类型,按照c++的方式来处理
template <typename T>
std::string TypeTraits(void (T::*)())
{
return std::string();
}
template <typename T>
T TypeTraits(T val)
{
return val;
}
//类型萃取,数据转换
template <typename T>
std::string TypeTraitsValue(T val, int T::*)
{
std::stringstream str;
str << val;
return str.str();
}
template <typename T>
T TypeTraitsValue(T val, ...)
{
return val;
}
template<typename T>
decltype(TypeTraits<T>(0)) ClassTraits(T val)
{
return TypeTraitsValue<T>(val, 0);
}
//格式化
std::string __format(const char *strFmt, ...);
template<typename...Args>
std::string __args(const char *strFmt, Args...args)
{
return __format(strFmt, DataTraits(std::forward<Args>(args))...);
}
template<typename...Args>
std::string format(const char *strFmt, Args...args)
{
return __args(strFmt, ClassTraits(std::forward<Args>(args))...);
}
std::string format(const char *strFmt);
实现文件:
std::string format(const char *strFmt)
{
return strFmt;
}
std::string __format(const char *strFmt, ...)
{
#ifdef _WIN32
va_list vl;
va_start(vl, strFmt);
int count = _vscprintf(strFmt, vl); //_vsctprintf(format, vl);
va_end(vl);
char *pszBuf = new char[count + 1];
va_start(vl, strFmt);
vsprintf_s(pszBuf, count + 1, strFmt, vl); //_vstprintf_s
va_end(vl);
std::string msg(pszBuf);
delete pszBuf;
return msg;
#else
va_list vl;
va_start(vl, strFmt);
char *pszBuf = NULL;
int count = vasprintf(&pszBuf, strFmt, vl); //_vsctprintf(format, vl);
va_end(vl);
std::string msg(pszBuf);
free(pszBuf);
return msg;
#endif
}
来源:oschina
链接:https://my.oschina.net/u/3312209/blog/4304331