【问题标题】:Template iterator inside template class, clang cannot infer template parameter模板类中的模板迭代器,clang 无法推断模板参数
【发布时间】:2014-06-28 12:07:05
【问题描述】:

我有一个带有嵌套模板自定义迭代器(专门用于 const/non-const 迭代器)的模板类,如下所示:

template <typename T>
struct A
{
    template <typename U>
    struct AIterator
    {
        //...
    };

    typename AIterator<T*> iterator;
    typename AIterator<const T*> const_iterator;
};

template <typename T>
bool operator==(const typename A<T>::iterator& lhs,
                const typename A<T>::iterator& rhs,)
{
    //...
}

template <typename T>
bool operator!=(const typename A<T>::iterator& lhs,
                const typename A<T>::iterator& rhs,)
{
    //...
}

//idem for const_iterator...

但是clang无法推断出模板参数:

snake_test.cpp:17:68: error: invalid operands to binary expression ('wavelet::Snake<float>::const_iterator' (aka 'Iterator<const float *>') and 'const_iterator' (aka 'Iterator<const float *>'))
        for (wavelet::Snake<float>::const_iterator it = snake.begin(); it != snake.end(); it++)
                                                                       ~~ ^  ~~~~~~~~~~~
./snake.hpp:150:6: note: candidate template ignored: couldn't infer template argument 'T'
bool operator!=(const typename Snake<T>::iterator& lhs,
     ^
./snake.hpp:164:6: note: candidate template ignored: couldn't infer template argument 'T'
bool operator!=(const typename Snake<T>::const_iterator& lhs,
     ^
1 error generated.

我做错了什么?如何正确实现模板类的自定义迭代器?

【问题讨论】:

  • 一方面,您的参考标签在您的论点的错误方面。例如:lhs&amp; 应该是 &amp;lhs 等。rhs 参数后面的逗号也没有多大帮助。
  • 谢谢!我在写这个问题时正在做饭,所以我写得很快,因此它可能会留下一些错别字。 ;-)
  • 您是否尝试过在A 中定义operator==operator!=
  • 函数模板函数参数的嵌套名称说明符中的模板参数处于非推导上下文中。 IE。在A&lt;T&gt;::iteratorT不能推导出来。
  • @matovitch 二元运算符(两个操作数)由于对称性而被实现为非成员函数。这允许 LHS 和 RHS 进行相同的转换(考虑 struct BigInt { BigInt(int); }; BigInt b; 42 == b)并且“更干净”,因为通常此类运算符无论如何都是可交换的,这意味着 LHS 和 RHS 具有相同的意义。

标签: c++ templates iterator clang++


【解决方案1】:

可能最简单和最干净的解决方案是使用在类体内定义的非成员友元函数:

template <typename T>
struct A
{
    template <typename U>
    struct AIterator
    {
        friend bool operator==(AIterator const& lhs, AIterator const& rhs)
        { /* implement here */ }
    };

    typename AIterator<T*> iterator;
    typename AIterator<const T*> const_iterator;
};

这将为AIterator 的每个特化创建一个非成员函数。据我所知,您不能在外部为这个非成员函数提供定义——它不是函数模板,而是每个专业化的适当函数。所以你只能在全局命名空间中定义一组固定的特化。

【讨论】:

  • 我不完全确定为什么嵌套类型在非推导上下文中。乍一看,类型中似乎没有任何信息可以将其与其周围的范围相关联;这可能与透明的 typedef 有关。我不明白为什么不可能关联有关周围范围的信息,但推断它可能会导致微妙的问题。
  • 谢谢!我也在想朋友。 :-)
  • This other answer 非常有帮助!:从一个类型到它的封闭类型基本上没有一一对应的关系,因此并不总是保证封闭类型甚至是可推导出的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2010-12-22
  • 2017-03-22
  • 2020-07-01
  • 2013-02-18
  • 1970-01-01
相关资源
最近更新 更多