每个字符串向量的c ++

时间:2013-05-29 09:28:35

标签: c++ for-loop std

    typedef std::vector<std::string> TVector;
    TVector a_list;

    populate vector...
    for_each(a_list.begin(),a_list.end(),std::toupper);

错误

no matching function for call to 'for_each(std::vector<std::basic_string<char> >::iterator, std::vector<std::basic_string<char> >::iterator, <unresolved overloaded function type>)

我是否需要使用标准for循环遍历元素?或者是否有其他方式我不允许使用c ++ 11功能。

谢谢

3 个答案:

答案 0 :(得分:4)

toupper函数用于字符,而非字符串。它还返回大写字符,因此不适用于for_each,但会使用std::transform。还有一个问题是std::toupper存在于两个重载中,并且编译器无法决定使用哪一个。包括<cctype>并使用普通toupper(或可选::toupper)来获得正确的功能。

您需要首先遍历向量中的所有字符串,然后再次遍历字符串以调用toupper

您可以手动执行此操作,也可以使用transform并使用functor objects,例如

struct strtoupper
{
    std::string operator()(const std::string& str) const
    {
        std::string upper;
        std::transform(str.begin(), str.end(), std::back_inserter(upper), ::toupper);
        return upper;
    }
};

// ...

std::transform(a_list.begin(), a_list.end(), a_list.begin(), strtoupper());

答案 1 :(得分:3)

您的向量为std::stringstd::toupper需要char作为参数。所以它无法使用。你能做的是:

std::for_each(list.begin(), list.end(),[](std::string& s) { std::for_each(s.begin(), s.end(), std::toupper);});

答案 2 :(得分:2)

std::toupper是一个重载函数;这就是你在错误信息中收到<unresolved overloaded function type>的原因。要选择特定的重载,您需要将其强制转换:

static_cast<int(*)(int)>(std::toupper)

for_each也不是此任务的正确选择 - 它将为列表中的每个字符串调用toupper,然后丢弃结果。 std::transform将是合适的选择 - 它将其输出写入输出迭代器。但是,toupper适用于字符,而不是字符串。您仍然可以使用transform为字符串中的每个字符调用toupper

std::transform(
    a_string.begin(),
    a_string.end(),
    a_string.begin(),
    static_cast<int(*)(int)>(std::toupper)
);

在这个简单的情况下使用循环可能会更清楚:

for (TVector::iterator i = a_list.begin(), end = a_list.end(); i != end; ++i) {
    for (std::string::size_type j = 0; j < i->size(); ++j) {
        (*i)[j] = toupper((*i)[j]);
    }
}

但是,如果您只想使用<algorithm><iterator>工具编写它,那么您可以创建一个仿函数:

struct string_to_upper {
    std::string operator()(const std::string& input) const {
        std::string output;
        std::transform(
            input.begin(),
            input.end(),
            std::back_inserter(output),
            static_cast<int(*)(int)>(std::toupper)
        );
        return output;
    }
};

// ...

std::transform(
    a_list.begin(),
    a_list.end(),
    a_list.begin(),
    string_to_upper()
);