шаблонный кастинг C++ с производными классами

#include <vector>

struct A {int a;};
struct B : public A {char b;};

int main()
{
  B b;
  typedef std::pair<A*, A*> MyPair;
  std::vector<MyPair> v;
  v.push_back(std::make_pair(&b, &b)); //compiler error should be here(pair<B*,B*>)
  return 0;
}

Я не понимаю, почему это компилирует (возможно, кто-то может любезно дать подробное объяснение? Это - что-то связанное с поиском имени?

Btw, на Солярисе, SunStudio12 это не компилирует: error : formal argument x of type const std::pair<A*, A*> & in call to std::vector<std::pair<A*,A*> >::push_back(const std::pair<A*, A*> & ) is being passed std::pair<B*, B*>

5
задан Paul Floyd 16 July 2017 в 21:17
поделиться

2 ответа

std::pair имеет конструктор шаблона:

template<class U, class V> pair(const pair<U, V> &p);

"Effects: Инициализирует члены из соответствующих членов аргумента, выполняя неявные преобразования по мере необходимости". (C++03, 20.2.2/4)

Преобразование из производного указателя класса в указатель базового класса неявно.

13
ответ дан 18 December 2019 в 14:46
поделиться

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

Смешайте это с помощью передачи или синхронизации сообщений между потоками, которые вы выполняете явно, и легко в конечном итоге с тупиками. Итак, в целом вам лучше убедиться, что вы зарезервируете основную нить для вашего пользовательского интерфейса и выполняете всю обработку в других потоках, которые не имеют пользовательского интерфейса.

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

-121--2964762-

, потому что B выводится из A, вектор V будет содержать указатели на структуры базовых классов объекта b. Поэтому вы можете получить доступ к членам A, I.E.

std::cout << v[0].first->a;

Редактирование: Моя ошибка, как указано ниже, вы все еще можете отбрасывать на указатели типа B, так как вектору представляет собой указатели, а не объекты, поэтому нажатие объекта не произошло.

Вызов, такой как

std::cout << v[0].first->b; 

, не скомпилируется, поскольку элементы в векторе являются базовыми указателями класса, и не могут указывать на полученные классы, без литого, то есть

 std::cout << static_cast<B*>(v[0].first)->b; 

также обратите внимание, что динамический листок, как в

std::cout << dynamic_cast<B*>(v[0].first)->b;  

Не будет компилировать со следующей ошибкой в ​​GCC:

cast.cpp:14: error: cannot dynamic_cast ‘v.std::vector<_Tp, _Alloc>::operator[] [with _Tp = std::pair<A*, A*>, _Alloc = std::allocator<std::pair<A*, A*> >](0u)->std::pair<A*, A*>::first’ (of type struct A*’) to type struct B*’ (source type is not polymorphic)
0
ответ дан 18 December 2019 в 14:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: