实现是否应该防止逗号重载?

时间:2012-01-03 22:56:48

标签: c++ language-lawyer comma-operator

例如,uninitialized_copy在标准中定义为:

  

效果:

for (; first != last; ++result, ++first)
  ::new (static_cast<void*>(&*result))
    typename iterator_traits<ForwardIterator>::value_type(*first);

如果从字面上理解,则需要调用operator ,(ForwardIterator, InputIterator)。事实上,这段代码打印Hello world!十次:

#include <memory>
#include <iterator>
#include <iostream>

using namespace std;

namespace N {     
    struct X : iterator<forward_iterator_tag, int> {
        pointer _p;
        X(pointer p) : _p(p) {}
        X& operator++() { ++_p; return *this; }
        X operator++(int) { X r(*this); ++_p; return r; }
        reference operator*() const { return *_p; }
        pointer operator->() const { return _p; }
    };

    bool operator==(X a, X b) { return a._p == b._p; }
    bool operator!=(X a, X b) { return !(a == b); }

    void operator,(X a, X b) { cout << "Hello world!\n"; }
}

int a[10], b[10];

int main()
{
    using N::X;
    uninitialized_copy(X(a), X(a+10), X(b));
}

然而,对于大多数其他算法,该标准在散文中给出了描述。例如。对于copy,不需要调用运算符,。但是如果我改变了

    uninitialized_copy(X(a), X(a+10), X(b));

在上面的代码中

    copy(X(a), X(a+10), X(b));

然后Hello world! 仍然打印了十次。 VS2005和GCC 4.3.4都可以观察到上述结果。但是,如果我写

    mismatch(X(a), X(a+10), X(b));
相反,然后VS2005打印Hello world!十次,但GCC不打印。

不幸的是我无法找到标准禁止operator,重载迭代器类型的位置。相反,它禁止实现如上所述进行调用[global.functions]:

  

除非另有说明,否则标准库中的全局函数和非成员函数不得使用通过参数依赖名称查找(3.4.2)找到的另一个命名空间中的函数。

那么四方中谁是错的:MSVC,GCC,ISO还是我? (选择一个)

1 个答案:

答案 0 :(得分:3)

很好听。我认为,我认为ISO委员会的意图是遵循§3.4.2。 uninitialized_copy的建议语义被错误地解释为需要调用逗号。并且实现不应该使用它(我向gcc btw报告错误)。