stl — Должны ли стандартные библиотеки C ++ поддерживать классы, которые требовательны к тому, кто их друзья?

Этот вопрос проще всего проиллюстрировать на примере, поэтому здесь идет речь:

Является ли код, подобный следующему, гарантированно верным и & бежать правильно?

(Не все реализации на самом деле компилируют его правильно, но мне интересно, если это ошибка.)

#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;
}

8

Решение

std::copy требуется выходной итератор ([gorithms.general] / p5); итераторы вывода, помимо прочего, требуют *r = o быть действительным ([output.iterators], таблица 108), а не просто «иногда допустимо» или «допустимо в некоторых контекстах».

Так как для Picky *p, a;, *p = a не действует в большинстве случаев, Picky * не является допустимым итератором вывода.


Хм, было бы здорово, если бы вы могли обобщить свой ответ на другие вещи
за конкретный пример, который я дал. Как, например,
std::vector::push_back(T const &)или что угодно.

Подружиться с функцией-членом — абсолютное нет-нет, потому что вы даже не гарантированы, что есть функция-член с этой подписью ([member.functions] / p2, которую Стефан Т. Лававей называет «Исполнители STL могут быть хитрым правилом»):

Реализация может объявить дополнительную не виртуальную функцию-член
подписи внутри класса:

  • путем добавления аргументов со значениями по умолчанию к сигнатуре функции-члена187 [Заметка: Реализация
    не может добавлять аргументы со значениями по умолчанию для виртуальных, глобальных функций или функций, не являющихся членами. — конечная нота];
  • путем замены сигнатуры функции-члена значениями по умолчанию двумя или более сигнатурами функции-члена с эквивалентным поведением; а также
  • добавив сигнатуру функции-члена для имени функции-члена.

187 Следовательно, адрес функции-члена класса в стандартной библиотеке C ++ имеет неопределенный тип.

8

Другие решения

Код может скомпилироваться, если std::copy() не вызывает никаких других не дружественных функций, но мне еще не приходилось сталкиваться с такой реализацией. И нет никаких требований в стандартном ограничении, КАК std::copy() достигается необходимый эффект.

Однако для этого требуется работающий и доступный оператор присваивания.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector