C++ 标准库必须支持 类 对他们的朋友是谁很挑剔吗?
Must the C++ standard library support classes that are picky about who their friends are?
这个问题最容易用例子来说明,所以这里是:
像下面这样的代码是否保证有效,并且运行正确编译?
(并非所有实现都能正确编译它,但我想知道这是否是一个错误。)
#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;
}
std::copy
需要一个输出迭代器 ([algorithms.general]/p5);输出迭代器,除其他外,要求 *r = o
有效 ([output.iterators], Table 108) - 不仅仅是 "valid sometimes" 或 "valid in some contexts".
由于 Picky *p, a;
,*p = a
在大多数情况下无效,Picky *
不是有效的输出迭代器。
Hmm it'd be great if you could generalize your answer to other things
beyond the particular example I gave. Like, for example,
std::vector::push_back(T const &)
, or whatever.
与成员函数交朋友是绝对不行的,因为你甚至不能保证有一个带有该签名的成员函数([member.functions]/p2,Stephan T. Lavavej 称之为 "STL Implementers Can Be Sneaky Rule"):
An implementation may declare additional non-virtual member function
signatures within a class:
- by adding arguments with default values to a member function signature187 [Note: An implementation
may not add arguments with default values to virtual, global, or non-member functions. — end note];
- by replacing a member function signature with default values by two or more member function signatures with equivalent behavior; and
- by adding a member function signature for a member function name.
187 Hence, the address of a member function of a class in the C++ standard library has an unspecified type.
如果 std::copy()
不调用任何其他非友元函数,代码可能会编译,但我还没有遇到任何此类实现。并且标准限制中没有要求如何std::copy()
达到要求的效果。
但是,它确实需要一个有效且易于访问的赋值运算符。
这个问题最容易用例子来说明,所以这里是:
像下面这样的代码是否保证有效,并且运行正确编译?
(并非所有实现都能正确编译它,但我想知道这是否是一个错误。)
#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;
}
std::copy
需要一个输出迭代器 ([algorithms.general]/p5);输出迭代器,除其他外,要求 *r = o
有效 ([output.iterators], Table 108) - 不仅仅是 "valid sometimes" 或 "valid in some contexts".
由于 Picky *p, a;
,*p = a
在大多数情况下无效,Picky *
不是有效的输出迭代器。
Hmm it'd be great if you could generalize your answer to other things beyond the particular example I gave. Like, for example,
std::vector::push_back(T const &)
, or whatever.
与成员函数交朋友是绝对不行的,因为你甚至不能保证有一个带有该签名的成员函数([member.functions]/p2,Stephan T. Lavavej 称之为 "STL Implementers Can Be Sneaky Rule"):
An implementation may declare additional non-virtual member function signatures within a class:
- by adding arguments with default values to a member function signature187 [Note: An implementation may not add arguments with default values to virtual, global, or non-member functions. — end note];
- by replacing a member function signature with default values by two or more member function signatures with equivalent behavior; and
- by adding a member function signature for a member function name.
187 Hence, the address of a member function of a class in the C++ standard library has an unspecified type.
如果 std::copy()
不调用任何其他非友元函数,代码可能会编译,但我还没有遇到任何此类实现。并且标准限制中没有要求如何std::copy()
达到要求的效果。
但是,它确实需要一个有效且易于访问的赋值运算符。