2010-02-19 5 views
1

Supposons que j'ai quelque chose comme ceci:sizeof (...) = 0 ou déclaration variable conditionnelle en C++ modèles

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

Maintenant, je peux perdre jusqu'à 19bytes par PoorMansTuple.

Question est:

1) Est-il possible de créer une classe de taille 0?

2) Existe-t-il un moyen de définir de manière conditionnelle une varaible? Somethign aiment:

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

Merci!

L'utilisation de macros magiques noires est préméditée. J'utilise g ++ sur Mac OS X.

+0

Pouvez-vous sauvegarder un peu et nous dire plus généralement ce que vous essayez de faire? Il se peut qu'il y ait une solution plus simple à votre problème général. –

Répondre

4

La spécialisation partielle peut être ce que vous recherchez pour la première partie de la question. Ce programme

#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; 
} 

impressions

<string, string>: 32 
<string, empty> : 16 
<string>  : 16 
+0

(+1) Vous pouvez réduire la quantité de code nécessaire en dérivant le 2-tuple du 1-tuple - de cette façon, vous n'avez qu'à définir «T2 t2;» dans le 2-tuple. Pour généraliser cela, il vous suffit de définir un membre par (n + 1) -tuple en dérivant du n-uplet. –

1

1) Non, car l'instance de la classe ne peut pas avoir d'adresse mémoire. Il faut au moins 1 octet pour avoir une adresse. - Cela dit, une classe qui n'a pas d'instance et de référence directe (utilisée uniquement lors de la génération du template par exemple) n'aura pas de taille car elle ne sera pas dans le programme compilé.

2) Pas sans macro ... ou peut-être obscur modèle noir arts que seuls les ninjas boost.org peuvent maîtriser. J'ai entendu parler de l'idée de «si» à la compilation, mais ce n'est pas actuellement le cas dans la langue AFAIK. Cela l'aurait permis. Comme déjà dit, peut-être il y a un truc pour le faire.

1

Découvrez boost::tuple et boost::compressed_pair. Une classe ne peut pas avoir une taille de 0, mais il y a le concept de l'optimisation "classe de base vide". Eh, je vais juste faire un lien vers une de mes réponses précédentes, c'est assez pertinent ici IMO: What is std::pair?