简体   繁体   English

每个字符串向量的c ++

[英]c++ for each vector of strings

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

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

error 错误

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>)

Do I need to iterate over the elements using the a standard for loop ? 我是否需要使用标准for循环遍历元素? Or is there another way I am not allowed to use c++ 11 features. 或者是否有另一种方法我不允许使用c ++ 11功能。

Thanks 谢谢

The toupper function is used for characters , not strings. toupper函数用于字符 ,而不是字符串。 It also returns the uppercase character, so won't work with for_each , but will with std::transform . 它也返回大写字符,因此不能使用for_each ,但会使用std::transform There is also the problem that std::toupper exists in two overloads, and the compiler can't decide which one to use. 还有一个问题是std::toupper存在于两个重载中,编译器无法决定使用哪一个。 Include <cctype> and use plain toupper (or optionally ::toupper ) to get the right function. 包括<cctype>并使用plain toupper (或者可选::toupper )来获得正确的功能。

You need to iterate first over all strings in the vector, and the iterate again over the string to call toupper . 您需要首先遍历向量中的所有字符串,然后再次遍历字符串以调用toupper

You can either do it manually, or use transform and use functor objects , something like 你可以手动完成,也可以使用transform和使用仿函数对象

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());

You have a vector of std::string and std::toupper expects a char as parameter. 你有一个std::string的向量, std::string std::toupper需要一个char作为参数。 So it can not be used. 所以它无法使用。 What you can do is: 你能做的是:

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

std::toupper is an overloaded function; std::toupper是一个重载函数; that's why you're getting <unresolved overloaded function type> in the error message. 这就是您在错误消息中获得<unresolved overloaded function type>的原因。 To select a particular overload, you need to cast it: 要选择特定的重载,您需要将其强制转换:

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

for_each is also not the right choice for this task—it will call toupper for each string in the list, then discard the result. for_each也不是这个任务的正确选择 - 它会为列表中的每个字符串调用toupper ,然后丢弃结果。 std::transform would be the appropriate choice—it writes its output to an output iterator. std::transform将是合适的选择 - 它将其输出写入输出迭代器。 However, toupper works on characters, not strings. 但是, toupper适用于字符,而不是字符串。 You could still use transform to call toupper for each character in a string: 您仍然可以使用transform为字符串中的每个字符调用toupper

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

It would probably be clearer in this simple case to use loops: 在这个简单的情况下使用循环可能会更清楚:

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]);
    }
}

But if you wanted to write it with <algorithm> and <iterator> tools only, you could make a functor: 但是如果你只想用<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()
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM