【问题标题】:what is the wrong with this example in the c++ book of Bjarne StroustrupBjarne Stroustrup 的 c++ 书中的这个例子有什么问题
【发布时间】:2016-12-21 14:56:06
【问题描述】:

我尝试了 bjarne stroustrup 的 c++ 编程语言第 4 版中的示例:

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

template<typename T>
using Iterator<T> = typename T::iterator;

template<typename C, typename V>
vector<Iterator<C>> find_all(C& c, V v)
{
    vector<Iterator<C>> res;
    for (auto p = c.begin(); p!=c.end(); ++p)
        if (*p==v)
            res.push_back(p);
    return res;
}

void test()
{
    string m {"Mary had a little lamb"};
    for (auto p : find_all(m,'a'))
        if (*p!='a')
            cerr << "string bug!\n";
    // p is a str ing::iterator
    list<double> ld {1.1, 2.2, 3.3, 1.1};
    for (auto p : find_all(ld,1.1))
        if (*p!=1.1)
            cerr << "list bug!\n";
    vector<string> vs { "red", "blue", "green", "green", "orange", "green" };
    for (auto p : find_all(vs,"green"))
        if (*p!="green")
            cerr << "vector bug!\n";
    for (auto p : find_all(vs,"green"))
        *p = "ver t";
}

int main()
{
    test();
    return 0;
}

§4.5.1

我使用以下代码编译代码: g++ test.cpp -o test -g -std=c++11 在 ubuntu 上,但出现以下错误:

iterator_of_iterator_version_2.cpp:9:15: error: expected ‘=’ before ‘<’ token
 using Iterator<T> = typename T::iterator;
               ^
iterator_of_iterator_version_2.cpp:9:15: error: expected type-specifier before ‘<’ token
iterator_of_iterator_version_2.cpp:12:8: error: ‘Iterator’ was not declared in this scope
 vector<Iterator<C>> find_all(C& c, V v)
        ^
iterator_of_iterator_version_2.cpp:12:17: error: template argument 1 is invalid
 vector<Iterator<C>> find_all(C& c, V v)
                 ^
iterator_of_iterator_version_2.cpp:12:17: error: template argument 2 is invalid
iterator_of_iterator_version_2.cpp:12:18: error: expected unqualified-id before ‘>’ token
 vector<Iterator<C>> find_all(C& c, V v)
                  ^
iterator_of_iterator_version_2.cpp: In function ‘void test()’:
iterator_of_iterator_version_2.cpp:24:30: error: ‘find_all’ was not declared in this scope
  for (auto p : find_all(m,'a'))
                              ^
iterator_of_iterator_version_2.cpp:29:31: error: ‘find_all’ was not declared in this scope
  for (auto p : find_all(ld,1.1))
                               ^
iterator_of_iterator_version_2.cpp:33:35: error: ‘find_all’ was not declared in this scope
  for (auto p : find_all(vs,"green"))
                                   ^
iterator_of_iterator_version_2.cpp:36:35: error: ‘find_all’ was not declared in this scope
  for (auto p : find_all(vs,"green"))
                                   ^

那么问题出在哪里?

在这段代码中似乎没有发现语法错误,因为我只是复制粘贴了本书的示例。

【问题讨论】:

  • @Someprogrammerdude 我这样做了,同样的错误
  • @Someprogrammerdude gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
  • 应该是'template using Iterator = typename T::iterator'
  • 您是否正确复制了书中的代码?因为就像@jonas_toth 说你不应该有类型别名的模板参数。
  • 我对其进行了快速测试,使用相同的编译器进行编译。 太多了

标签: c++ c++11


【解决方案1】:

改变开头

template<typename T>
using Iterator<T> = typename T::iterator;

template<typename T>
using Iterator = typename T::iterator;

在我的 ubuntu 16.04 上工作,编译器设置可能相同

为什么会这样?我对此不是 100% 有信心,请其他人验证一下。

写作

using Iterator<T>

无效,因为它在这里没有意义。我们希望 Iterator 是一个模板化的 typedef,它将向其参数类型询问其通用迭代器类型。 Iterator&lt;T&gt; 将专门化模板。 例如。我们更了解特定类型:

template<>
using Iterator<MyClass> = MyClassIterator;

至少这适用于普通模板类,我认为使用也是一样的。

【讨论】:

  • 但是你能解释一下吗?为什么会这样?
  • 这是相当语法的。使用 Iterator 将是模板专业化(我猜),但现在需要。需要的是一个模板迭代器。但我对它背后的 c++ 语言要求没有信心。我会用我天真的理解在答案中更新它
  • 这是示例代码中的拼写错误。它发生了。可能该示例是在 using 模板别名语法不同或不存在时编写的!
  • 更新了帖子,也许现在更清楚为什么它有问题(并且有一个错误的错误消息:D)
【解决方案2】:

改变这个

 template<typename T>
 using Iterator<T> = typename T::iterator;

到这里

template<typename T>
using Iterator = typename T::iterator;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多