在看《STL 源码剖析》这本书第 3.2 节 iterator 的时候,想要尝试实现一下书中的 list 例子。遇到了一点小问题。
我用的编译器是 clang 7.0, 没有完全按照书中的写法,用了一些 C++11 的语法。但是在 编译时遇到了错误,源码如下:
mylist.h:
1 | #include <iostream> |
mylist-test.cc:
1 | #include "mylist.h" |
编译用的命令为:
1 | clang++ mylist-test.cc -std=c++11 |
得到了如下的错误提示:
1 | In file included from mylist-test.cc:2: |
开始我以为是这个实现没有遵循 C++ 标准中 iterator 的规范,少了一些 typedef 之类的
定义,于是我在 ListIter
加了一行:
1 | typedef std::forward_iterator_tag iterator_category; |
重新编译时发现错误提示并没有什么变化,我以为定义了这个类型就会提示其他错误,想之 后再根据提示修改的。但是错误提示没有变化说明可能不是这个错误原因。然后换了 g++ 重新编译还是同样的错误信息。
最后突然想到 clang 默认是使用 libstdc++ 的,g++ 也是,换成 libc++ 不知道会不会给 出更显示的错误提示,于是改为链接 libc++:
1 | clang++ mylist-test.cc -std=c++11 -stdlib=libc++ |
结果直接编译成功了。其中的原因还不清楚。
2018-08-27:
g++ 编译不通过的原因应该是 ListIter
没有定义五种相应的类型,即1
Member type | Definition |
---|---|
iterator_category | Category |
value_type | T |
difference_type | Distance |
pointer | Pointer |
reference | Reference |
书中 3.5 节给出了正确的方法,即从 std::iterator
继承:
1 | template <class Item> |
我自己尝试在类中手工定义一下这几个类型,也可以使 g++ 通过编译。
clang++ 在不定义这几个类型时也能编译通过的原因还是不清楚。。。