sizeof () = 0 или объявление условной переменной в шаблонах c ++

Предположим, у меня есть что-то вроде этого:

struct EmptyClass{};
template<typename T1, typename T2 = EmptyClass,
         typename T3 = EmptyClass, typename T4 = EmptyClass,
         ..., typename T20> class PoorMansTuple {
  T1 t1;
  T2 t2;
  ...
  T20 t20;
};

Теперь я могу тратить до 19 байт на одну PoorMansTuple.

Вопрос такой:

1) Есть ли способ создать класс размера 0?

2) Есть ли способ условно определить переменную? Что-то вроде:

  T1 t1;
  if (T2 != EmptyClass) T2 t2; // pseudo code
  if (T3 != EmptyClass) T3 t3; // ...

Спасибо!

Использование макросов черной магии разрешено.

Я использую g ++ в MacOSX.


person anon    schedule 19.02.2010    source источник
comment
Не могли бы вы немного отступить и в более общем плане рассказать нам, что вы пытаетесь сделать? Возможно, есть более простое решение вашей общей проблемы.   -  person Jeff Wilhite    schedule 19.02.2010


Ответы (4)


Частичная специализация может быть тем, что вы ищете в первой части вопроса. Эта программа

#include <string>
#include <iostream>

struct EmptyClass {};

template<typename T1, typename T2>
class Tuple
{
   T1 t1;
   T2 t2;
};

template<typename T1>
class Tuple <T1, EmptyClass>
{
   T1 t1;
};


int main (void)
{
    Tuple<std::string, std::string> two;
    Tuple<std::string, EmptyClass> one1;
    Tuple<std::string> one2;

    std::cout << "<string, string>: " << sizeof(two) << std::endl;
    std::cout << "<string, empty> : " << sizeof(one1) << std::endl;
    std::cout << "<string>        : " << sizeof(one2) << std::endl;

    return 0;
}

отпечатки

<string, string>: 32
<string, empty> : 16
<string>        : 16
person Lars    schedule 19.02.2010
comment
(+1) Вы можете сократить объем необходимого кода, производя кортеж из 2 элементов из кортежа из 1 - таким образом вам нужно только определить T2 t2; в кортеже из 2 элементов. Обобщая это, вам нужно определить только один член на (n + 1) -кортеж, производный от n-кортежа. - person Georg Fritzsche; 19.02.2010

1) Нет, потому что у экземпляра класса не может быть адреса памяти. Для адреса требуется как минимум 1 байт. - при этом класс, у которого нет экземпляра и прямой ссылки (например, используется только при генерации шаблона), не будет иметь размера, поскольку его нет в скомпилированной программе.

2) Не без макросов ... или, может быть, неясных шаблонных черных артов, которые могут освоить только ниндзя boost.org. Я слышал об идее «если» во время компиляции, но в настоящее время этого нет ни в одном из будущих стандартов языка AFAIK. Это позволило бы это. Как уже было сказано, может быть, есть хитрость, чтобы это сделать.

person Klaim    schedule 19.02.2010

  1. У класса должен быть какой-то размер (хотя бы один). См. «Какой минимальный размер объекта возможен в C / C ++?»
  2. AFAIK, нет, вы не можете.
person paleozogt    schedule 19.02.2010

Проверьте boost::tuple и boost::compressed_pair. Класс не может иметь размер 0, но существует концепция оптимизации «пустой базовый класс». Эх, я просто собираюсь сослаться на один из моих предыдущих ответов, здесь он очень актуален, ИМО: Что такое std :: pair?

person Logan Capaldo    schedule 19.02.2010