Russian Qt Forum
Ноябрь 23, 2024, 03:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: static_cast элементов в контейнере  (Прочитано 13231 раз)
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #15 : Январь 28, 2015, 10:17 »

Расскажите, не читал  Улыбающийся
std::vector<bool> хранит каждое значение в отдельном бите, т.е. его внутреннее устройство кардинально отличается std::vector<T>. Специализированные методы соответственно заточены для такого хранения. Если попробовать привести вектор bool к какому нибудь vector<char>, то получиться "каша".
Так же я могу специализировать любую коллекцию. Например, vector<Base*> будет стандартной реализации, а vector<Derived*> моей собственной, не имеющей ничего общего со стандартной.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #16 : Январь 28, 2015, 10:57 »

vector<Base*> и vector<Derived*> генерируют два совершенно разных класса. Только то, что они оба унаследованы от vector<void*> не приводит к ошибке.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #17 : Январь 28, 2015, 11:10 »

vector<Base*> и vector<Derived*> генерируют два совершенно разных класса. Только то, что они оба унаследованы от vector<void*> не приводит к ошибке.
Как правило, устройство и внутренности у них одинаковы, поэтому и не приводит к ошибке. А я могу так специализировать вектор, что устройство и внутренности у него будут совершенно другие.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Январь 28, 2015, 12:31 »

std::vector<bool> хранит каждое значение в отдельном бите, т.е. его внутреннее устройство кардинально отличается std::vector<T>.
Не знал об этом, спасибо

Так же я могу специализировать любую коллекцию. Например, vector<Base*> будет стандартной реализации, а vector<Derived*> моей собственной, не имеющей ничего общего со стандартной.
Это предполагает непосредственное участие "злобного Буратино" - а без этого все одинаково, можно сказать "байт в байт". sizeof одинаков, конструктор/деструктор для указателей одинаков. Поэтому опасения преувеличены, хотя конечно конструкция "с душком"

vector<Base*> и vector<Derived*> генерируют два совершенно разных класса. Только то, что они оба унаследованы от vector<void*> не приводит к ошибке.
Во всяком случае здесь "унаследованы" - неверный термин
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #19 : Январь 28, 2015, 13:05 »

Во всяком случае здесь "унаследованы" - неверный термин
Согласен.
Вот записки одного злого гения!

Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #20 : Январь 28, 2015, 13:08 »

А я могу так специализировать вектор, что устройство и внутренности у него будут совершенно другие.
А вы про указатели говорите? Как это сделать?
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #21 : Январь 28, 2015, 13:54 »

А вы про указатели говорите? Как это сделать?

Да как и с любым другим типом:
Код
C++ (Qt)
#include <vector>
#include <list>
#include <iostream>
 
template<class T>
class vec
{
public:
vec()
{
std::cerr << "vec::vec( T )" << std::endl;
}
 
std::vector<T> m_mem;
};
 
template<>
class vec<char*>
{
public:
vec()
{
std::cerr << "vec::vec( char * )" << std::endl;
}
 
std::list<char*> m_mem;
};
 
int main( int, char ** )
{
vec<void*> buf1;
vec<int*> buf2;
vec<char*> buf3;
 
return 0;
}
 

Цитировать
vec::vec( T )
vec::vec( T )
vec::vec( char * )
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #22 : Январь 28, 2015, 14:07 »

Я подумал, что вы про класс вектор из библиотеки.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #23 : Январь 28, 2015, 14:11 »

Я подумал, что вы про класс вектор из библиотеки.

 Строит глазки

Код
C++ (Qt)
namespace std
{
 
template<>
class vector<char*>
{
public:
vector()
{
std::cerr << "vec::vec( char * )" << std::endl;
}
 
std::list<char*> m_mem;
};
 
}
 
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #24 : Январь 28, 2015, 14:12 »

Строит глазки
Я подозревал, что это последует Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Январь 28, 2015, 15:27 »

Код
C++ (Qt)
namespace std
{
 
template<>
class vector<char*>
{
public:
vector()
{
std::cerr << "vec::vec( char * )" << std::endl;
}
 
std::list<char*> m_mem;
};
 
}
 
Правильно ли я понял что эта реализация НЕ может использовать ничего из vector <T>? (все требуемые методы надо писать самому)
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #26 : Январь 28, 2015, 15:33 »

Правильно ли я понял что эта реализация НЕ может использовать ничего из vector <T>? (все требуемые методы надо писать самому)
Если вы внутри все делаете по своему, то конечно все методы (точнее все используемые методы) придется делать самому.
Записан
Akon
Гость
« Ответ #27 : Январь 28, 2015, 20:20 »

Код:
        const bool is_compatible_containers =
            std::is_same< _SourceContainerTemplate<_SourceItem, _SourceAlloc>
                        , _DestContainerTemplate<_SourceItem, _SourceAlloc>>::value
Вот это никогда не вычислится в true.
Для одного и того же типа контейнера будет true, в примере на это проверка и нацелена. ...
Согласен. Я почему то воспринял первый аргумент в DestContainerTemplate как _DestItem (где были мои глаза  Улыбающийся).

Цитировать
const int dummy_object = 444555;
_SourceItem const source_item = (_SourceItem) dummy_object;
_DestItem const dest_item = static_cast<_DestItem> (source_item);
const bool is_compatible_inheritance = (int) dest_item == dummy_object;
static_assert(is_compatible_inheritance, "Incompatible inheritance");
Такого рода подход я и использовал для рантайм проверки. Уже не помню, почему не удалось в компайл-тайм. Уменя тогда были gcc 4.6 и msvc2010. Возможно, с gcc был компайл-тайм.

Друзья, я полностью согласен с тем, что частичной или полной специализацией можно изменить потроха контейнера, в результате реинтерпрет потеряет всякий смысл. Но я рассматриваю релевантные практике варианты.

Зайду с другой стороны - как вы реализуете метод MyContainer::items() в этом примере:
Код:
class Contaier;

class Item
{
public:
Container* container() { return container_; }

private:
Container* container_;
}

class Container
{
public:
vector<Item*> items() { return items_; }

protected:
void addItem(Item* item)
{
...
items_.push_back(item);
}

private:
vector<Item*> items_;
}

class MyContainer;

class MyItem : public Item
{
public:
MyContainer* container() { return static_cast<MyContainer*>(Item::container()); }
}

class MyContainer : public Container
{
public:
// ну а как вы поступите здесь с Container::items()?
vector<MyItem*> items() { return ??? }

void addItem(MyItem* item)
{
Container::addItem(item);
}
}
Все, что требуется в этом примере - это чтобы MyContainer возвращал MyItems тем же способом, как это делает Container.

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Февраль 01, 2015, 14:15 »

Код:
	// ну а как вы поступите здесь с Container::items()? 
vector<MyItem*> items() { return ??? }
Да просто
Код
C++ (Qt)
vector<MyItem*> items() { return (vector<MyItem*> &) Container::items(); }  // Waring: HACK
 
Провериться в compile/run-time по-моему недостижимо если базовый класс не полиморфный (vector<Item*>).   
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.239 секунд. Запросов: 23.