[英]C++ check if element is std::vector
我想遍历向量,并检查元素是向量还是字符串。 我也需要一种将不同的vecor传递给函数的方法。 像这样:
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
然后我需要知道如何为函数定义参数以接受任何种类的(多维)向量
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
通常,例如, <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 ++惯用的语言,您可能最好选择其他方法。
众所周知,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
模板的不同实例toCustomString<vector<string>>(const vector<vector<string>>&)
。 中间情况试图实例化toCustomString<int>
,但是失败了,因为toCustomString(v[i])
与它所知道的任何函数都不匹配。
所有这些都是在编译时确定的。 模板的重点是创建多个函数(或类),它们之间有特定的区别。 在这种情况下,区别在于传入的向量的类型。
[*]这似乎与您要求行vec[i]
必须是一个向量或字符串,没有任何第三种选择。 例如,如果您希望vector<something_else>
的返回值为空,则可以添加一个包罗万象的模板:
template <typename T>
string toCustomString(const T &) {
return string();
}
当然,您可以为要处理的任何其他类型添加更多重载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.