【问题标题】:Compile error with decltype of iterator de-reference使用 decltype 的迭代器取消引用编译错误
【发布时间】:2018-01-17 04:03:17
【问题描述】:

我在这里缺少什么?为什么我不能使用 decltype 来定义迭代器的 value_type?当我使用 decltype 而不是 iterator_traits 时,下面的代码会出现难以理解的编译时错误,但前提是我还使用 value_type 来声明向量。

Visual Studio 2017,C++17 修订版。 15.6 预览

#include <vector>
template<class Ptr >
void foo(Ptr beg) {
    *beg = 1;  // Cool, babies.
//  using value_type = decltype(*beg); // COMPILER ERROR when buf declared below
    using value_type = typename std::iterator_traits<Ptr>::value_type;
    std::vector<value_type> buf(1); // Remove this and decltype compiles.
}

int main() {
    std::vector<int> bar(1);
    foo(std::begin(bar));
    *(std::begin(bar)) = 1;
    return 0;
}

根据要求...

error C2528: 'const_pointer': pointer to reference is illegal

【问题讨论】:

  • 在问题中包含完整的编译器错误会很有帮助。
  • @chris - 我对此表示怀疑,但没关系。
  • 有人仁慈地删除了除第一行错误之外的所有错误。
  • decltype(*beg) 给出int&amp;,而不是int
  • @O'Neil - 啊哈。现在该怎么办?我宁愿避免 iterator_traits...

标签: c++ templates visual-c++ decltype c++17


【解决方案1】:

出于同样的原因,您有:

void foo(int *beg)

然后

decltype(*beg)

不给你int。你在这里得到一个int &amp;。从本质上讲,这就是您的 using 声明最终得到的:一个参考,一个不请自来的搭便车者。

如果你坚持使用decltype,你可以这样做:

using value_type = typename std::remove_reference<decltype(*beg)>::type;

为了摆脱不受欢迎的搭便车者。

【讨论】:

  • 我会注意到,如果给出了const_iterator,这仍然会失败,因为有一个const 事物的向量。在这种情况下,即将推出的std::remove_cv_t trait 更合适,它相当于std::remove_cv_t&lt;std::remove_reference_t&lt;T&gt;&gt;,或者你可以使用std::decay_t,这可能更适合获取无论如何都会存储在向量中的类型。跨度>
  • 它不是常量。实际代码是线程并行的 stable_sort。
  • 太棒了! Iterator_traits 不是必需的。问一个愚蠢的问题我一点也不尴尬。
猜你喜欢
  • 2012-02-03
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
相关资源
最近更新 更多