2008-10-28 7 views
2

j'avais la pièce de code suivant (simplifié pour cette question):pointeur à des données membres-de-données-membre

struct StyleInfo 
{ 
    int width; 
    int height; 
}; 

typedef int (StyleInfo::*StyleInfoMember); 

void AddStyleInfoMembers(std::vector<StyleInfoMember>& members) 
{ 
    members.push_back(&StyleInfo::width); 
    members.push_back(&StyleInfo::height); 
} 

Maintenant, nous avons dû restructurer cela un peu, et nous avons quelque chose comme ceci:

struct Rectangle 
{ 
    int width; 
    int height; 
}; 

struct StyleInfo 
{ 
    Rectangle size; 
}; 

typedef int (StyleInfo::*StyleInfoMember); 

void AddStyleInfoMembers(std::vector<StyleInfoMember>& members) 
{ 
    members.push_back(&StyleInfo::size::width); 
    members.push_back(&StyleInfo::size::height); 
} 

Si tout cela ressemble à une chose stupide à faire, ou si vous vous sentez qu'il ya une bonne occasion d'appliquer BOOST ici pour une raison quelconque, je dois vous avertir que je vraiment simplifié le tout à le problème à résoudre:

C3083 d'erreur: « taille »: le symbole à gauche d'un « :: » doit être un type

Le point que je suis en train de faire est que je ne sais pas ce que la syntaxe correcte est à utiliser ici. Il se peut que "StyleInfo" ne soit pas le bon type d'adresse pour commencer, mais dans mon projet je peux réparer ce genre de choses (il y a tout un cadre). Je ne sais tout simplement pas comment désigner ce membre-dans-un-membre.

+0

Tryout commentaire # 1 –

Répondre

2

Mais comme les membres normaux, vous ne pouvez pas accéder aux membres des sous-classes en utilisant le mécanisme d'accès des membres. Donc, ce que vous devez faire est d'y accéder comme si vous accédiez à un membre de l'objet (dans votre cas via le membre de taille).

#include <vector> 
#include <iostream> 


struct Rectangle 
{ 
    int width; 
    int height; 
}; 

struct StyleInfo 
{ 
    Rectangle size; 
}; 

typedef Rectangle (StyleInfo::*StyleInfoMember); 
typedef int   (Rectangle::*RectangleMember); 

typedef std::pair<StyleInfoMember,RectangleMember> Access; 

void AddStyleInfoMembers(std::vector<Access>& members) 
{ 
    members.push_back(std::make_pair(&StyleInfo::size,&Rectangle::width)); 
    members.push_back(std::make_pair(&StyleInfo::size,&Rectangle::height)); 
} 


int main() 
{ 
    std::vector<Access>  data; 
    AddStyleInfoMembers(data); 

    StyleInfo  obj; 
    obj.size.width = 10; 

    std::cout << obj.*(data[0].first).*(data[0].second) << std::endl; 
} 

Ce n'est pas quelque chose que je recommanderais de faire!

Une alternative (que je recommande encore moins) est de trouver le décalage d'octets depuis le début de la classe, puis de simplement l'ajouter à l'adresse des objets. Évidemment, cela impliquera beaucoup de coulée vers l'arrière et vers l'avant, donc cela semble encore pire que ce qui précède.

1

Est-ce vraiment possible? Honnêtement, je ne sais pas, n'ayant jamais joué beaucoup avec pointeur-à-membre. Supposons que vous utilisiez des types non-POD (je sais que vous ne l'êtes pas, mais la syntaxe devrait le prendre en charge). Ensuite, pointeur-à-membre pourrait avoir à encapsuler plus que juste un décalage du pointeur de base. Il peut également exister une indirection, selon la manière dont l'héritage multiple est implémenté. Avec plusieurs niveaux d'indirection de membre, cela pourrait devenir arbitrairement compliqué, ce qui est beaucoup demander un type qui doit avoir une taille fixe.

Peut-être vous avez besoin d'un vecteur de paires, de types définis par:

typedef Rectangle (StyleInfo::*StyleInfoMember); 
typedef int (Rectangle::*RectangleMember); 

Appliquer chacun à son tour pour arriver là où vous voulez être. Bien sûr, cela ne vous permet toujours pas de construire un vecteur de mappings d'un StyleInfo vers des membres arbitraires de StyleInfo, car ils ne passeraient pas tous par Rectangle. Pour cela, vous devrez peut-être ouvrir une boîte de foncteurs ...

+0

Je suis sur le point de céder et mordre la balle et font valoir qu'il est en effet pas possible.Bien sûr, il s'agit de tous les types de POD et le compilateur les réduira tous en offsets simples à utiliser pour accéder à ces membres. Mais cela ne veut pas dire qu'il existe un moyen de le faire correctement, contrairement à ce que vous suggérez. –

0
taille

(comme dans &StyleInfo::size::width) n'est pas le nom d'un type. au lieu

essayer taille-> largeur ou size.width, selon la façon dont votre « AddStyleInfoMembers` connaît la taille du tout. Rappelez-vous qu'un pointeur sur un membre est juste utilisé comme un membre.