C++ 使用g+;编译初级示例代码时出错+;在Ubuntu Linux上

C++ 使用g+;编译初级示例代码时出错+;在Ubuntu Linux上,c++,g++,C++,G++,代码来自C++初级读本(三分之三)。 错误是: *filterString.cpp:在函数“int main()”中: filterString.cpp:32:68:错误:无法在初始化中将“\uu gnu\u cxx::\uu normal\u iterator*,std::vector>>”转换为“std::string*{aka std::basic\u string}” 请帮我分析一下错误, 谢谢 代码: #包括 #包括 #包括 #包括 #包括 使用名称空间std; 模板 无效筛选器\字符

代码来自C++初级读本(三分之三)。 错误是:

*filterString.cpp:在函数“int main()”中: filterString.cpp:32:68:错误:无法在初始化中将“\uu gnu\u cxx::\uu normal\u iterator*,std::vector>>”转换为“std::string*{aka std::basic\u string}”

请帮我分析一下错误, 谢谢

代码:

#包括
#包括
#包括
#包括
#包括
使用名称空间std;
模板
无效筛选器\字符串(先输入筛选器,后输入筛选器,字符串筛选器元素=字符串(“\”,?”){
for(;first!=last;first++){
字符串::size\u type pos=0;
while((pos=(*first).find_first_of(filt_elems,pos))!=string::npos)
(*第一)。擦除(位置1);
}
}
布尔长度小于(字符串s1、字符串s2){
返回s1.size()size();
cout在第32行

std::max_element(text.begin(), text.end(), length_less);
此函数返回一个前向迭代器,该迭代器寻址搜索范围内第一个最大元素出现的位置,而不是字符串

您可以做什么来代替这一行:

string *max = max_element(text.begin(), text.end(), length_less);
你必须这样做

//First find the index of the max_element , by subtracting the forward iterator you get from calling max_element from the iterator for first element .

       int index=max_element(text.begin(), text.end(), length_less) - text.begin();

//And then find string stored on that index.

       string *max = text.at(index);

这很有趣。迭代器的行为很像指针,但并不完全一样。特别是,不能将迭代器转换为指针

但是,您可以将此代码更改为使用迭代器作为一种字符串*指针:

vector<string>::iterator max = max_element(text.begin(), text.end(), length_less);
*max_元素(…)返回对返回的迭代器指向的字符串的引用(就像取消引用实际指针一样),并创建指向该字符串的(字符串*)指针(&R)

这会带来麻烦,因为对向量的结构修改可能会悄悄地使该指针无效。后续使用该指针会将“随机”内存视为字符串对象。更糟糕的是,它可能在测试期间工作,直到软件发布后才会失败


一个好的迭代器实现应该能够检测到失效并抛出异常。一个可预测的失败比一个随机的崩溃要好。

好吧,所以我太过火了。下面是我认为使用lambdas和auto的更现代的解决方案。我让其他人来决定它是否更容易理解

#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <string>
#include <vector>

using namespace std;

template <class InputIterator>
void filter_string(InputIterator first, InputIterator last, 
                   const string filt_elems = const string("\",?.")) 
{
    for_each(first, last, 
        [filt_elems](string& s)
        {
            s.erase(
                // Shift valid characters up before erasing the undesirable
                remove_if(s.begin(), s.end(), 
                    [filt_elems](string::value_type c)
                    { return filt_elems.find_first_of(c) != string::npos; }), 
                s.end());
        });
}

int main()
{
    istream_iterator<string> input(cin);
    istream_iterator<string> eos;

    vector<const string> words;
    copy(input, eos, back_inserter(words));

    const string filt_elems("\",.?;:");
    filter_string(words.begin(), words.end(), filt_elems);
    const int count = words.size();

    // Get a reference to the longest word
    const auto& max_word = *max_element(words.cbegin(), words.cend(), 
        [](const string& lhs, const string& rhs)
        { return lhs.size() < rhs.size(); });
    const int length = max_word.size();

    cout << "The number of words read is " << count << endl;
    cout << "The longest word has a length of " << length << endl;
    cout << "The longest word is " << max_word << endl;

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
模板
无效筛选器\字符串(先输入计数器,后输入计数器,
常量字符串过滤器=常量字符串(“\”,?”)
{
每个(第一、最后、,
[filt_elems](字符串和s)
{
s、 抹去(
//在删除不需要的字符之前,将有效字符上移
如果(s.开始(),s.结束(),则删除,
[filt_elems](字符串::值类型c)
{return filt_elems.find_first_of(c)!=string::npos;}),
s、 end());
});
}
int main()
{
istream_迭代器输入(cin);
istream_迭代器eos;
向量词;
复制(输入、eos、背面插入器(文字));
常量字符串过滤器元素(“\”,.?;:”;
筛选字符串(words.begin()、words.end()、筛选元素);
const int count=words.size();
//获取最长单词的引用
const auto&max\u word=*max\u元素(words.cbegin(),words.cend(),
[](常量字符串和lhs、常量字符串和rhs)
{返回lhs.size()如果你是从一本书或其他旧的(在互联网时代)工作source随着时间的推移,您对语言的理解可能发生了变化。设置
-std=
可能会让您在编译器中使用早期的理解。抱歉,我不能完全理解。尤其是以下词语:“设置-std=可能会让您在编译器中使用以前的理解"。你能逐项解释一下吗!非常感谢!G++采用的参数形式为
std=c++98
std=c++=0x
。选择正确的参数可能会让G++处理代码。这与std名称空间无关,而是从函数中得到的。你得到一个正向迭代器,并将其转换为字符串。我得到了它。t非常感谢hanks.vector::iterator max=max_元素(text.begin(),text.end(),length_less);但我认为Mike Housky的答案更清楚!因此我接受他的答案。谢谢。我会将其改写为“迭代器的合理实现应该在编译时检测无效赋值并生成错误。”这就是GCC所做的事情。VisualC++产生了类似的错误。一边注释,一边用现代编译器,可以写“AutoMax = Max元素(Text。),Text。。关于编译时检测无效赋值:我认为这不太可行。这将要求编译器跟踪迭代器,而语言并没有真正做到这一点。当以前使用的迭代器仍在作用域内时,对集合进行结构修改并没有错误。这是对迭代器的使用这是一个错误…并且只有当集合决定特定的修改实际上应该使迭代器无效时。
string *max = &*max_element(text.begin(), text.end(), length_less);
#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <string>
#include <vector>

using namespace std;

template <class InputIterator>
void filter_string(InputIterator first, InputIterator last, 
                   const string filt_elems = const string("\",?.")) 
{
    for_each(first, last, 
        [filt_elems](string& s)
        {
            s.erase(
                // Shift valid characters up before erasing the undesirable
                remove_if(s.begin(), s.end(), 
                    [filt_elems](string::value_type c)
                    { return filt_elems.find_first_of(c) != string::npos; }), 
                s.end());
        });
}

int main()
{
    istream_iterator<string> input(cin);
    istream_iterator<string> eos;

    vector<const string> words;
    copy(input, eos, back_inserter(words));

    const string filt_elems("\",.?;:");
    filter_string(words.begin(), words.end(), filt_elems);
    const int count = words.size();

    // Get a reference to the longest word
    const auto& max_word = *max_element(words.cbegin(), words.cend(), 
        [](const string& lhs, const string& rhs)
        { return lhs.size() < rhs.size(); });
    const int length = max_word.size();

    cout << "The number of words read is " << count << endl;
    cout << "The longest word has a length of " << length << endl;
    cout << "The longest word is " << max_word << endl;

    return 0;
}