c++ - C++ 标准库必须支持对 friend 是谁挑剔的类吗?

标签 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;
}

最佳答案

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

因为对于 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.

与成员函数交 friend 是绝对不行的,因为你甚至不能保证有一个带有该签名的成员函数([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.

关于c++ - C++ 标准库必须支持对 friend 是谁挑剔的类吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30111320/

相关文章:

C++11 引入了采用 `const char*` 的异常构造函数。但为什么?

c++ - 是一个声明 void();合法的,实际上是什么?

c++ - 如何存储坐标以便与以后的坐标进行比较

c++ - 移动 std::set 后指针的有效性

c++ - 结束(结束后)迭代器的 STL 迭代器重新验证?

c++ - 如何在 std::vector 中找到元素位置?

c++ - 以毫秒为单位捕获时间

c++ - 为什么 std::memcpy 的行为对于不是 TriviallyCopyable 的对象是未定义的?

c++ - CRTP 避免虚拟成员函数开销

c++ - 尽可能按引用传递,否则按值传递