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

发布于 2024-12-23 18:49:43 字数 1813 浏览 2 评论 0原文

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

效果:

for (; 第一个 != 最后一个; ++结果, ++第一个)
  ::new (static_cast(&*结果))
    类型名 iterator_traits::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 不会。

不幸的是,我找不到标准在哪里禁止迭代器类型的运算符重载。相反,它禁止实现执行上述调用[global.functions]:

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

那么这四个方面谁错了:MSVC、GCC、ISO 还是我? (选择一项)

For example uninitialized_copy is defined in the standard as:

Effects:

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

If understood literally, this is a requirement to call operator ,(ForwardIterator, InputIterator). And in fact this code prints Hello world! ten times:

#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));
}

However, for most other algorithms the standard gives the description in prose. E.g. for copy there's no requirement for operator , to be called. But if I change

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

in the above code to

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

then Hello world! is still printed ten times. The said results are observable in both, VS2005 and GCC 4.3.4. However, if I write

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

instead, then VS2005 prints Hello world! ten times but GCC does not.

Unfortunately I couldn't find where the standard prohibits operator, overloading for iterator types. On the contrary, it prohibits the implementations to do calls as above [global.functions]:

Unless otherwise specified, global and non-member functions in the standard library shall not use functions from another namespace which are found through argument-dependent name lookup (3.4.2).

So who of the four parties is wrong: MSVC, GCC, ISO or me? (Choose one)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空气里的味道 2024-12-30 18:49:43

不错的收获。我认为,以我的拙见,ISO 委员会的意图是应遵循 §3.4.2。 uninitialized_copy 的建议语义被错误地解释为需要调用逗号。并且实现不应该使用它(顺便说一句,我会向 gcc 报告错误)。

Nice catch. I think in my humble opinion that the ISO committee's intention was that §3.4.2 should be followed. The suggested semantics of uninitialized_copy is wrongly interpreted as if requiring the comma to be called. And implementations should not be using it (I'd report a bug to gcc btw).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文