比较模板函数中两个不同类型的迭代器

时间:2013-08-28 11:41:55

标签: c++

没有C ++ 11或Boost :(

我有一个带有以下签名的函数。

template<class INPUT_ITR, class OUTPUT_ITR>
void DoWork(const INPUT_ITR in_it, const INPUT_ITR in_it_end, OUTPUT_ITR out_it, OUTPUT_ITR out_it_end, CONTEXT_DATA)

通常在输入和输出之间进行一些复杂的处理..但有时需要无操作,并且只是复制数据。如果输入和输出数据类型相同,则该函数支持就地操作。所以我有这个代码。

    if (NoOp)
    {
        if (in_it != out_it)
        {
            copy(in_it, in_it_end, out_it);
        }
    }

如果已请求就地操作(迭代器检查),则无需复制任何数据。

这个工作正常,直到我用迭代器调用函数到不同的数据类型(例如int32到int64)。然后它抱怨迭代器检查,因为它们是不兼容的类型。

error C2679: binary '!=' : no operator found which takes a right-hand operand of type 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<unsigned __int64>>>

这让我有点难过。如果数据类型相同,是否有一种简单的方法可以执行此检查,如果它们是不同的类型,只是执行复制?

由于

3 个答案:

答案 0 :(得分:4)

您可以将测试提取到一对模板中;一个用于匹配类型,一个用于非匹配类型。

template <class T1, class T2>
bool same(T1 const &, T2 const &) {return false;}

template <class T>
bool same(T const & a, T const & b) {return a == b;} 

请注意,当与您期望可比较的类型一起使用时,这会产生令人困惑的结果。在C ++ 11中(或者使用Boost,或者使用模板进行大量繁琐的工作),您可以扩展它以在可能的情况下比较不同的类型;但这超出了你的需要。

另外,请注意,您依赖于正式的未定义行为,因为不需要对不同基础序列的迭代器进行比较。从迭代器本身无法判断是否是这种情况。

答案 1 :(得分:1)

我想出了一个解决方法。欢迎任何更好的建议。

重载该函数以提供就地版本。由用户现在就地请求(使用旧函数就地将在没有操作的情况下执行冗余复制)。

template<class ITR>
void DoWork(const ITR it, const ITR it_end, CONTEXT_DATA)
{
    if (! NoOp)
    {
        DoWork(it, it_end, it, it_end, sSourceSpec, sDestSpec);
    }
}

答案 2 :(得分:0)

您可以使用std::iterator_traits和自定义is_same类型特征,因为您没有c ++ 11:

template<class T, class U>
struct is_same
{
   static const bool value = false;
};

template<class T>
struct is_same<T, T>
{
   static const bool value = true;
};

if(!is_same<typename std::iterator_traits<INPUT_ITR>::value_type, 
            typename std::iterator_traits<OUTPUT_ITR>::value_type>::value)
{
    copy(...);
}