1

没有 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>>>

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

谢谢

4

3 回答 3

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,或者使用模板进行大量繁琐的处理),您可以扩展它以尽可能比较不同的类型;但这超出了您在这里所需要的。

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

于 2013-08-28T11:56:04.847 回答
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);
    }
}
于 2013-08-28T11:52:48.293 回答
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(...);
}
于 2013-08-28T11:54:54.293 回答