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

Posted

技术标签:

【中文标题】实现是不是应该防止逗号重载?【英文标题】:Should the implementation guard itself against comma overloading?实现是否应该防止逗号重载? 【发布时间】:2012-02-01 22:32:16 【问题描述】:

例如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 还是我? (选择一项)

【问题讨论】:

我认为Visual C++、gcc和ISO都错了:Visual C++和gcc不应该使用逗号操作符,规范(ISO)也不应该在其示例代码中使用逗号。我可能是错的;这只是我对此事的第一个想法。 (请考虑在 Microsoft Connect 上打开一个 Visual C++ 错误;至少值得引起他们的注意。) 考虑到即使像 Size 这样的东西也是一个模板类型,我会转过头来说标准想要精确它所说的,如果您看到提供自定义逗号运算符的理由,然后您被邀请这样做,您将获得指定的行为。 @JamesMcNellis KerrekSB:谢谢。我希望有人能找到一个据说是未定义行为的地方,否则我们要打开三个错误报告。 @ybungalobill:仅供参考,您不能在一条评论中通知两个人。 【参考方案1】:

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

【讨论】:

这也是我的解释。逗号重载太疯狂了,我认为它只是滑过了我们委员会成员的注意力。 是的,从那以后我提交了 PR 和 AFAIK,他们修复了标准,随后流行的实现删除了意外的逗号运算符调用。

以上是关于实现是不是应该防止逗号重载?的主要内容,如果未能解决你的问题,请参考以下文章

实现 CSS:导航栏由于侧导航而崩溃 - 如何防止?

Spring 3.0.5中如何防止参数绑定解释逗号?

js实现的防止别人嵌套自己的页面

mysql-防止XSS攻击

防止刷新/后退引起的重复提交问题的Java Token代码,非Struts

Linux命令sudo实现集权(提权)管理,防止超级权限泛滥