LINUX.ORG.RU

Как задать пустой тип (нулевой длины) в качестве параметра шаблона что бы на поле соотв. типа не тратилась память?

 , ,


1

2

Сабж. Вот есть такой класс

template <typename T> class A{
   T p[256];
   ...
public:
   T get(int i) const { return p[i]; }
   vois set(int i, T x){ p[i] = x; }
};

В некоторых случаях поле p не нужно. Что передать в качестве параметра что бы на него не уходила память, но при этом все компилировалось? Спецификацию шаблона делать не хочется, будет много букв.

Ну или как нечто подобное сделать без спецификации?

★★★★

В некоторых случаях поле p не нужно

А как будут реализованы сеттер и геттер?

XMs ★★★★★
()

Сделай p* и malloc в конструкторе, когда надо.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)

В такой постановке вопроса - никак. Из-за оптимизации пустого базового класса. У каждого элемента массива должен быть адрес. Т.е. минимум 256 байт таки будет в памяти занимать.

Можно посмотреть на compile time условия, например на std::enable_if.

pon4ik ★★★★★
()
Ответ на: комментарий от AntonI

Тогда можно в базовом классе всё убрать, а в наследнике запилить

XMs ★★★★★
()
Ответ на: комментарий от pon4ik

std::enable_if.

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

делать не хочется, будет много букв.

Я бы через указатель сделал, причем верятно на stl вектор предпочел бы, чем указатель на массив или массив из 256 указателей

bonta ★★★★★
()
Ответ на: комментарий от pon4ik

enable_if че то не позволяет прибивать функции-члены класса... ну или у меня руки кривые.

AntonI ★★★★
() автор топика
Ответ на: комментарий от pon4ik

Блин, я туплю (все просто):

template <typename T> class C{
   T p[256];
public:
   T get(int i) const { return p[i]; }
   vois set(int i, T x){ p[i] = x; }
};

template <> struct C<void>{
   char get(int i) const { return 0; }
   vois set(int i, char x){}
};

template <typename T> class A: public C<T>{
...
};

Я таки не понял, может enable_if работать с функциями-членами класса, или нет?

AntonI ★★★★
() автор топика

В C++ sizeof даже для «пустых» типов будет равен 1. Потому как указатели на разные обьекты должны тоже отличатся.

Единственный случай, когда размер пустого обьекта (можно сказать) равен нулю — при наследовании:

struct Empty {};
static_assert(size of(Empty) == 1);

struct Derived : Empty {};
static_assert(size of(Derived) == 1);

Т.е. можно попробовать сделать что-то на основе...

Еще в C++20 появится аттрибут [[no_unique_address]] который расширяет возможности по созданию пустых обьектов.

https://en.cppreference.com/w/cpp/language/attributes/no_unique_address

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 1)
Ответ на: комментарий от AntonI

Можно std::is_same заместо флага использовать.

pon4ik ★★★★★
()
Ответ на: комментарий от AntonI

Вы хотите геттер и сеттер убрать вовсе? Тогда без специализации и наследования не обойтись. Сделайте базовый класс, где будет «всё остальное». Далее специализируйте наследника отдельно пустого типа, отдельно для остальных.

Crocodoom ★★★★★
()
Ответ на: комментарий от pon4ik

Я хотел избежать специализации всего шаблона (он большой). Кусочек то можно;-)

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

AntonI ★★★★
() автор топика
Ответ на: комментарий от crutch_master

Это долго рассказывать. AMR для числодробилок. Но экономия памяти там существенна;-)

AntonI ★★★★
() автор топика

Спецификацию шаблона делать не хочется, будет много букв.

Это C++, деточка, тут могут иerror: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating ‘struct W<W<W<W<W<W<W<W<W<...

Miguel ★★★★★
()

В C++ не бывает липов нулевой длины, даже struct{} занимает 1 байт. Сделай нормальную иерархию классов, где у тебя нет массива там где он не нужен вместо придумывания костылей.

slovazap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.