我想创建一个包含嵌入信息的字符串.实现我想要的一种方式(不是唯一的方法)称为字符串插值或变量替换,其中字符串中的占位符用实际值替换.
在C中,我会做这样的事情:
printf("error! value was %d but I expected %d",actualValue,expectedValue)
Run Code Online (Sandbox Code Playgroud)
而如果我在python中编程,我会做这样的事情:
"error! value was {0} but I expected {1}".format(actualValue,expectedValue)
Run Code Online (Sandbox Code Playgroud)
这两个都是字符串插值的例子.
我怎么能用C++做到这一点?
重要提示:
std::cout如果我想将这样的消息打印到标准输出(不是字符串插值,但打印出我想要的字符串类型):cout << "error! value was " << actualValue << " but I expected "
<< expectedValue;
Run Code Online (Sandbox Code Playgroud)
我不想将字符串打印到stdout.我想将std::string一个参数作为参数传递给一个函数(例如异常对象的构造函数).
编辑
对于我的直接使用,我并不关心性能(我正在大声提出异常!). 但是,了解各种方法的相对性能通常非常有用.
为什么不直接使用printf(毕竟C++是C的超集......)? 这个答案讨论了一些原因.根据我的理解,类型安全是一个重要原因:如果你把%d放在那里,你放在那里的变量最好真的可以转换为整数,因为这就是函数如何计算它是什么类型.使用一种方法可以更加安全,该方法使用要插入的变量的实际类型的编译时知识.
inf*_*inf 36
在 C++20 中,您将能够使用std::format.
这将支持 python 样式格式:
string s = std::format("{1} to {0}", "a", "b");
Run Code Online (Sandbox Code Playgroud)
已经有一个可用的实现:https : //github.com/fmtlib/fmt。
sto*_*tic 16
方法1:使用字符串流
它看起来像std::stringstream一个快速的解决方案:
std::stringstream ss;
ss << "error! value was " << actualValue << " but I expected " << expectedValue << endl;
//example usage
throw MyException(ss.str())
Run Code Online (Sandbox Code Playgroud)
正
负
方法2:提升格式
该升压格式库也是一种可能性.使用这个,你会做:
throw MyException(boost::format("error! value was %1% but I expected %2%") % actualValue % expectedValue);
Run Code Online (Sandbox Code Playgroud)
正
负
编辑:
方法3:可变参数模板参数
似乎可以通过使用可变参数模板参数(对于采用无限数量模板参数的模板的技术术语)来创建类型安全的printf版本.我已经看到了这方面的一些可能性:
正
负
在C++ 11中,您可以使用std::to_string:
"error! value was " + std::to_string(actualValue) + " but I expected " + std::to_string(expectedValue)
Run Code Online (Sandbox Code Playgroud)
它不漂亮,但它很简单,你可以使用宏来缩小它.性能不是很好,因为你reserve()事先没有空间.Variadic模板可能更快,看起来更好.
这种字符串结构(而不是插值)对于本地化也是不好的,但如果需要,你可能会使用库.
使用任何你喜欢的:
1) std::stringstream
#include <sstream>
std::stringstream ss;
ss << "Hello world!" << std::endl;
throw std::runtime_error(ss.str());
Run Code Online (Sandbox Code Playgroud)
2)libfmt:https : //github.com/fmtlib/fmt
#include <stdexcept>
throw std::runtime_error(
fmt::format("Error has been detected with code {} while {}",
0x42, "copying"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18009 次 |
| 最近记录: |