C ++标准库必须支持那些对他们的朋友是谁的挑剔的类吗?

时间:2015-05-07 20:45:28

标签: c++ stl language-lawyer friend access-modifiers

这个问题最容易用一个例子说明,所以这里有:

以下代码是否保证有效,并且编译&运行正确吗?

(并非所有实现都能正确编译它,但我想知道这是否是一个错误。)

#include <algorithm>
class Picky
{
    friend
        Picky *std::copy<Picky const *, Picky *>(Picky const *, Picky const *, Picky *);
    Picky &operator =(Picky const &) { return *this; }
public:
    Picky() { }
};

int main()
{
    Picky const a;
    Picky b;
    std::copy<Picky const *, Picky *>(&a, &a + 1, &b);
    return 0;
}

2 个答案:

答案 0 :(得分:8)

std::copy需要输出迭代器([algorithms.general] / p5);输出迭代器,除其他外,要求*r = o有效([output.iterators],表108) - 不仅“有时有效”或“在某些情况下有效”。

因为对于Picky *p, a;*p = a在大多数情况下无效,Picky *不是有效的输出迭代器。

  

如果你可以概括你对其他事情的回答,那就太好了   超出我给出的特定例子。比如,例如,   std::vector::push_back(T const &)或其他什么。

与成员函数交友绝对禁止,因为你甚至不能保证有一个带有该签名的成员函数([member.functions] / p2,Stephan T. Lavavej称之为"STL Implementers Can Be Sneaky Rule" ):

  

实现可以声明其他非虚拟成员函数   班级中的签名:

     
      
  • 通过将默认值的参数添加到成员函数签名 187 [注意:一个实现   可能不会将具有默认值的参数添加到虚拟,全局或非成员函数。 - 结束记录];
  •   
  • 通过两个或多个具有等效行为的成员函数签名替换具有默认值的成员函数签名;和
  •   
  • 通过为成员函数名称添加成员函数签名。
  •   
     

187 因此,C ++标准库中类的成员函数的地址具有未指定的类型。

答案 1 :(得分:1)

如果std::copy()没有调用任何其他非朋友功能但我还没有遇到任何此类实现,则代码可能会编译。并且标准限制HOW std::copy()没有要求达到所需的效果。

但是,它确实需要一个可操作且可访问的赋值运算符。