首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:Stroustrup iterator_traits示例未编译?

C++:Stroustrup iterator_traits示例未编译?
EN

Stack Overflow用户
提问于 2020-05-29 21:51:25
回答 3查看 83关注 0票数 0

我正在尝试编译来自Stroustrups C++第4版第124和125节Iterator特性的代码。不幸的是,编译会导致许多错误,这些错误看起来像是模板系统中的错误。有人知道这个代码有什么问题吗?

谢谢

代码语言:javascript
复制
#include <iostream>
#include <iterator>
#include <algorithm>
#include <forward_list>
#include <vector>
using namespace std;

template<typename Ran>
void sort_helper(Ran beg, Ran end, random_access_iterator_tag)
{
    sort(beg, end);
}

template<typename For>
void sort_helper(For beg, For end, forward_iterator_tag)
{
    vector<decltype(*beg)> v {beg, end};
    sort(v.begin(), v.end());
    copy(v.begin(), v.end(), beg); 
}

template<typename C>
using Iterator_type = typename C::iterator;

template<typename Iter>
using Iterator_category = typename std::iterator_traits<Iter>::iterator_category;

template<typename C> void sort(C& c)
{
    using Iter = Iterator_type<C>; // ex. vector<int>::iterator
    sort_helper(c.begin(), c.end(), Iterator_category<Iter>{});
}

int main(int argc, char *argv[])
{
    forward_list<int> fl = {2, 1, 0};
    vector<int> v = {2, 1, 0};

    sort(fl); // this line causes compilation error
    sort(v);

    return 0;
}

错误:

代码语言:javascript
复制
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/x86_64-linux-gnu/bits/c++allocator.h:33,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/allocator.h:46,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/string:41,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/locale_classes.h:40,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/ios_base.h:41,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ios:42,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ostream:38,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/iostream:39,
                 from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ext/new_allocator.h: In instantiation of 'class __gnu_cxx::new_allocator<int&>':
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/allocator.h:116:11:   required from 'class std::allocator<int&>'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_vector.h:87:21:   required from 'struct std::_Vector_base<int&, std::allocator<int&> >'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_vector.h:389:11:   required from 'class std::vector<int&, std::allocator<int&> >'
<source>:17:28:   required from 'void sort_helper(For, For, std::forward_iterator_tag) [with For = std::_Fwd_list_iterator<int>]'
<source>:31:16:   required from 'void sort(C&) [with C = std::forward_list<int>]'
<source>:39:12:   required from here
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ext/new_allocator.h:62:26: error: forming pointer to reference type 'int&'
   62 |       typedef _Tp*       pointer;
      |                          ^~~~~~~
... and more ...
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-05-29 22:00:34

您需要实例化一个vector<int>,但是

代码语言:javascript
复制
std::vector<decltype(*beg)>

给出一个std::vector<int&>

相反,您应该使用迭代器的value_type

代码语言:javascript
复制
std::vector<typename For::value_type> v {beg, end};

这是一个演示

票数 3
EN

Stack Overflow用户

发布于 2020-05-29 22:08:08

这是书中已知的错误。

来自printing3.html

pg 125:s/decltype(*beg)/Value_type<For>/修复解密类型的使用将占用比我在这里更多的空间。

票数 3
EN

Stack Overflow用户

发布于 2020-05-29 22:14:15

在函数sort_helper

代码语言:javascript
复制
template<typename For>
void sort_helper(For beg, For end, forward_iterator_tag)
{
    vector<decltype(*beg)> v {beg, end};
    sort(v.begin(), v.end());
    copy(v.begin(), v.end(), beg); 
}

在本声明中

代码语言:javascript
复制
vector<decltype(*beg)> v {beg, end};

模板参数的推导类似于引用类型。因此,在这个语句中,声明了一个无效的引用向量。

将此语句更改为

代码语言:javascript
复制
vector<std::decay_t<decltype( *beg )>> v {beg, end};

您需要包含头<type_traits>

或者可以显式地指定删除引用,如

代码语言:javascript
复制
vector<typename std::remove_reference<decltype( *beg )>::type> v {beg, end};

代码语言:javascript
复制
vector<typename std::remove_reference_t<decltype( *beg )>> v {beg, end};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62095110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档