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

Meh*_*dad 8 c++ stl access-modifiers friend language-lawyer

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

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

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 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实施者可能是偷偷摸摸的规则"):

实现可以在类中声明其他非虚拟成员函数签名:

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

187因此,在C++标准库中的类的成员函数的地址都有一个未指定的类型.

  • @Mehrdad不,你不能.标准实际上是在脚注中引用它,我在报价中添加了它. (3认同)