2

我想遍历一个向量并检查元素是向量还是字符串。我还需要一种将不同的向量传递给函数的方法。像这样的东西:

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

  • 然后我需要知道如何定义函数的参数以接受任何类型的(多维)向量

4

3 回答 3

6

std::vector只能包含一种类型——即Tin std::vector<T>,可以通过 member 访问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

于 2012-10-18T14:55:27.603 回答
2

通常,例如,您<some vector> vec的类型 vector<string> or vector<vector<string>>

为了声明变量,您需要它的类型,并且它的类型还准确地指定了它存储的内容。

现在,您可以使用Boost.Variant(或滚动您自己的可区分联合)来解决此问题,如下所示:

typedef boost::variant<std::string, std::vector<std::string>> Vec_of_StringOrVec;

但是 Dirk Holsopple 是正确的,这不是惯用的 C++,您最好寻找一种不同的方法。

于 2012-10-18T14:59:54.743 回答
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)重载。

如果有人将 avector<int>传入toCustomString,则代码将无法编译,因为(当前)没有toCustomString(int)重载 [*]。

如果有人通过 a vector<vector<string>>to toCustomStringthentoCustomString(vec[i])将通过 a vector<string>,见上文。

在所有三种情况下,都会调用不同 toCustomString的函数。在第一种情况下它是toCustomString<string>(const vector<string>&),这是toCustomString与第三种情况不同的模板实例化,toCustomString<vector<string>>(const vector<vector<string>>&)。中间情况尝试实例化toCustomString<int>,但由于toCustomString(v[i])不匹配它知道的任何函数而失败。

所有这些都是在编译时确定的。模板的重点是创建多个函数(或类),它们之间有特定的差异。在这种情况下,区别在于传入的向量类型。

[*] 这似乎符合您的要求,即vec[i]必须是向量字符串,而不是任何第三个选项。例如,如果您希望 a 的返回值为vector<something_else>空,则可以添加一个包罗万象的模板:

template <typename T> 
string toCustomString(const T &) { 
    return string(); 
}

当然,您可以为要处理的任何其他类型添加更多重载。

于 2012-10-18T15:14:29.170 回答