我想迭代一个向量并检查元素是否为向量或字符串。此外,我需要一种方法将不同的vecors传递给一个函数。 像这样:
using namespace std;
string toCustomString(<some vector> vec) {
string ret = "";
for(size_t i = 0; i < vec.length(); ++i)
if (vec[i] == %vector%)
ret += toCustomString(vec[i]);
else //if type of vec[i] is string
ret += "foo"+vec[i]+"bar";
}
return ret;
}
嗯,首先我需要知道如果vec [i]是std :: vector
然后我需要知道如何为函数定义参数,以接受任何类型的(多维)向量
答案 0 :(得分:6)
std::vector
只能包含一种类型 - 即T
中的std::vector<T>
,可以使用value_type
成员访问。
您可能正在寻找的是模板专业化:
template<typename T>
string toCustomString(std::vector<T> vec) {
// general case
}
template<>
string toCustomString<std::string>(std::vector<std::string> vec) {
// strings
}
(如果你想在所有向量上部分专门化它,那么你需要将它提升到一个结构)
如果你真的想在向量中存储字符串和向量,那么看看Boost.Variant和Boost.Any
答案 1 :(得分:2)
通常,您的<some vector> vec
的类型 vector<string>
或 vector<vector<string>>
。
为了声明变量,你需要它的类型,它的类型也确切地指定它存储的内容。
现在,您可以使用Boost.Variant解决此问题(或滚动您自己的歧视联盟),如下所示:
typedef boost::variant<std::string, std::vector<std::string>> Vec_of_StringOrVec;
但是Dirk Holsopple是对的,这不是惯用的C ++,你可能最好不要寻找不同的方法。
答案 2 :(得分:0)
正如大家所说,C ++中的向量只包含一种类型。依次检查每个元素的类型是没有必要或没有意义的,因为没有办法做到这一点。你所做的是重载参数类型的函数。像这样:
string toCustomString(const string &str) {
return "foo" +str + "bar";
}
template <typename T>
string toCustomString(const std::vector<T> &vec) {
string ret;
for(size_t i = 0; i < vec.size(); ++i)
ret += toCustomString(vec[i]);
return ret;
}
现在,如果有人将vector<string>
传递给toCustomString
,则来电toCustomString(vec[i])
会选择toCustomString(const string &str)
超载。
如果有人将vector<int>
传递给toCustomString
,则代码将无法编译,因为(当前)没有toCustomString(int)
重载[*]。
如果有人将vector<vector<string>>
传递给toCustomString
,则toCustomString(vec[i])
会传递vector<string>
,请参阅上文。
在所有三种情况下,都会调用不同的 toCustomString
函数。在第一种情况下,它是toCustomString<string>(const vector<string>&)
,它是来自第三种情况toCustomString
的{{1}}模板的不同实例。中间案例尝试实例化toCustomString<vector<string>>(const vector<vector<string>>&)
,但失败是因为toCustomString<int>
与它所知道的任何函数都不匹配。
所有这些都是在编译时确定的。模板的要点是创建多个函数(或类),它们之间存在特定的差异。在这种情况下,差异是传入的向量的类型。
[*]这似乎符合您声称toCustomString(v[i])
必须 向量或字符串,而不是任何第三个选项。如果您希望vec[i]
的返回值为空,那么您可以添加一个包罗万象的模板:
vector<something_else>
当然,您可以为要处理的任何其他类型添加更多重载。