Лучший способ обработать std :: reference_wrapper <Derived>как std :: reference_wrapper <Base> - PullRequest
2 голосов
/ 11 октября 2019

У меня есть два класса, скажем 'Base' и 'Derived', где Derived класс наследует Base класс.

Затем контейнер ссылок на экземпляры производного класса (std::vector< std::reference_wrapper< Derived > > myContainer).

И, наконец, у меня есть функция, которая принимает std::vector< std::reference_wrapper< Base > > в качестве аргумента.

Если я передаю контейнер (myContainer) в функцию, он не компилируется:

enter image description here

Если я изменю свой контейнер для хранения ссылок на Base, все будет работать нормально, и, поскольку это - reference_wrapper, я считаю, что у меня все еще будет полиморфное поведениечто мне нужноНо это кажется нечистым, так как я уверен, что мой контейнер не будет содержать ничего, кроме производных экземпляров.

В то же время функция, которая принимает вектор, должна работать как с производными, так и с базовыми классами.

Минимальный код:

#include <vector>
#include <functional>

class Base
{ /*some virtual stuff*/ };

class Derived : public Base
{};

void Fun( std::vector< std::reference_wrapper< Base > > const & container )
{}

int main()
{
    std::vector< std::reference_wrapper< Derived > > myContainer;
    Fun( myContainer ); // Error: no viable conversion
    return 0;
}

Живой код: https://godbolt.org/z/SX5Gag

Как лучше всего попросить функцию рассматривать контейнер производных ссылок как вектор базыссылки

1 Ответ

3 голосов
/ 11 октября 2019

Это просто невозможно:

std::vector< std::reference_wrapper< Derived > > d;
std::vector< std::reference_wrapper< Base > >& b = d;

Что могло бы произойти, если бы это было законно?

SomeOtherDerivedClass o;
b.push_back(o); // sure, b is vector of Base, so legal

Но b на самом деле просто ссылка на d, так что вам просто удалосьпоместите другой, недопустимый тип в d.

Так что если некоторые, даже если Base является базовым классом Derived, то же самое не относится к соответствующим контейнерам, будь то std::vector или любой другойдругой.

...