variadic宏可从未知参数集合中生成字符串向量
variadic macro to generate a vector of strings from a collection of unknown parameters
当前,我正在处理类似于c 中C#的String.Format(...)
函数的函数。(string.format(...))
但这不是我的问题。该功能正常工作,但有问题的是,它将vector<string>
作为参数,如果我想将整数用作参数,我必须像这样编写代码:
// function prototype, the function body is not relevant here
string format(string str, vector<string> variables);
// ... some context
// i could use to_string() here,
// but imagine a complex type which only overrides the stream operator
int a = 20;
stringstream ss;
ss << a;
string a_str = format("a has the value '{}'", { ss.str() });
这是相当多的样板代码!
因此,我需要一个将未知数据类型的集合转换为 vector<string>
的函数。
我尝试了一些这样的事情:
vector<string> vec_string(vector<void*> args) {
vector <string> result;
for (unsigned i = 0; i < args.size(); i++)
{
stringstream ss;
// I can't dereference an object without knowing to pointer type. :(
ss << *((int*)args[i]);
result.push_back(ss.str());
}
return result;
}
// ... some context
int a = 10;
cout << format("some int: '{}'", vec_string({ (void*) &a }));
显然仅适用于整数,并且非常不舒服。我觉得这样做的唯一方法是 variadic宏,但我不知道它们是如何工作的。
这是指向我的format(...)
方法的链接。我对自己的拼写感到抱歉,但我尝试了最好的纠正。
使用变异模板可以相对轻松地完成:
template <class T>
auto toString(T&& t) {
std::stringstream s;
s << std::forward<T>(t);
return s.str();
}
template <class... T>
auto toStringVector(T&&... args) {
std::vector<std::string> res {toString(std::forward<T>(args))...};
return res;
}
这将通过stringstream
将每个参数转换为std::string
,然后返回包含上述字符串的std::vector<std::string>
。(实时示例。)
然后,您可以按照问题的意图直接使用此直接,即:
std::cout << format("some text", toStringVector(any, number, of, arguments,
of, any, type));
如果您使用的是Boost,则可以跳过toString
助手,而支持boost::lexical_cast
:
template <class... T>
auto toStringVector(T&&... args) {
std::vector<std::string> res { boost::lexical_cast<std::string>(std::forward<T>(args))...};
return res;
}
lexical_cast
在内置类型上很可能会更快。
我弄清楚了,不知道我是在第一次尝试时如何做到这一点 - 没有编译器错误,但这就是我的做法:
// function prototype, the function body is not relevant here
string format(string str, vector<string> variables);
template <class T>
vector<string> paramsToString(vector<string> vec, T last) {
stringstream ss;
ss << last;
vec.push_back(ss.str());
return vec;
}
template <class T, class ... REST>
vector<string> paramsToString(vector<string> vec, T next, REST ... rest) {
stringstream ss;
ss << next;
vec.push_back(ss.str());
return paramsToString(vec, rest...);
}
template <class ... ARGS>
vector<string> paramsToString(ARGS ... args) {
return paramsToString(vector<string>(), args ...);
}
// ... some context
// ComplexType overrides the stream operator.
cout << format("an int: '{0}', and string: '{1}' and some other type: '{2}'",
paramsToString(10, "Hello World", ComplexType(10)));
它有效!即使使用自定义类型。惊人!
谢谢大家的帮助!
相关文章:
- 在 C++11 中,如何查找并返回以给定字符串开头的字符串向量中的所有项?
- 在将字符串放入字符串向量时遇到问题?
- 如何从字符串向量构造对象并避免复制?
- 如何在目录及其子文件夹中构建文件名字符串向量?
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 将字符串向量中的字符串放入主字符串中
- 如何在 c++ 中从字符串向量中读取
- 用字符串的向量分配字符串向量
- 如何使用 STL 算法将整数向量转换为字符串向量?
- C++ 中字符串向量的索引
- 如何根据第二列/第三列等对字符串向量进行排序?
- 如何从输入中获取字符串向量?
- 使用 C++-17,如何从字符串向量填充元组
- 对于循环增量器不能用作字符串向量的索引
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 如何从字符串向量中选择第 n 个位置?
- 如何将csv中的数据放入c++中的字符串向量中,而绝对没有任何作用
- 反转不带反转函数的字符串向量
- 如何在字符串向量中指向const int
- 如何在字符串向量中找到某个值