c++ - 为什么 decltype() 产生一个指向引用的指针?

标签 c++ decltype iterator-traits

我试图更好地了解 iterator_traits,并在 C++ 教科书中找到了一段代码。因此,我添加了一些代码以使其可执行,目的是了解所述编译时机制的行为。完整的程序如下所示:

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

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

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

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

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

void test(std::vector<std::string>& v, std::forward_list<int>& lst)
{
    sort(v);     
    sort(lst);   
}

template<typename C>
void print(C& c)
{
    for(auto it = c.begin(); it != c.end(); ++it) {
        std::cout << *it << '\n';
    }
    std::cout << '\n';
}

int main()
{
    std::vector<std::string> v { "Bicycle", "Hoovercraft", "Rocket", "Airplaine", "Bus", "Submarine" };
    print(v);

    sort(v);
    print(v);

    std::forward_list<int> lst { 2, 81, 3, 0, 4, 34, 23, 11 };
    print(lst);

    sort(lst);
    print(lst);

    return 0;
} 

编译失败,表明给出了指向引用的指针:

memory:1723:16: error: 
  'pointer' declared as a pointer to a reference of type 'int &'
typedef _Tp*              pointer;

错误堆栈显示以下行:

in instantiation of template class 'std::__1::vector<int &,     std::__1::allocator<int &> >'
  requested here
std::vector<decltype(*beg)> v {beg, end};

此编译可在 Mac OS 和使用 g++Linux 计算机上进行。

我成功地修改了涉及的部分,如下所示:

auto i = *beg;
std::vector<decltype(i)> v {beg, end};

您能否更清楚地解释一下为什么 decltype() 函数返回指向引用的指针?我读过一些关于 SO 上的 decltype 类型函数的其他问题,也阅读了规范,但都没有让我走上正确的道路,检查输出消息的完整编译器堆栈也没有任何帮助。

预先感谢您的考虑。

最佳答案

问题是decltype产生一个引用类型(你不能创建 std::vector )。
为什么会这样回答 here深入。

您可以通过以下两种方法之一修复它:

  • 使用std::remove_reference<decltype(*beg)>::type
  • 使用std::iterator_traits<For>::value_type

关于c++ - 为什么 decltype() 产生一个指向引用的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45980366/

相关文章:

c++ - 请帮助使用 MFC CMap(或 std::map)

c++ - 通过 C++ 中的 SOCI/ODBC 的 SQL Server 存储过程

c++ - decltype 行为背后的基本原理是什么?

c++ - const_iterator 和 const_iterator::value_type 的 constness

rust - 编写具有适用于 Vec 和数组 [] 的特征的 Rust 函数

c++ - 为什么 reverse_iterator 双重定义其嵌套类型?

c++ - 为什么我的应用程序在删除时崩溃?

c++ - x64 上的 mingw dw2 异常

C++:如何使用 decltype 从迭代器获取类型

c++ - decltype(void()) 中的 void() 究竟是什么意思?