2010-09-03 5 views
4

En C++, la compilation du code ci-dessous:Est-il possible de "consolider" un champ de "std :: pair" sans hacks?

std::pair <int, int> x; 
static_cast <std::pair <const int, int>*> (&x); 

donne une erreur:

error: invalid static_cast from type ‘std::pair<int, int>*’ to type ‘std::pair<const int, int>*’ 

je plus ou moins comprendre pourquoi il arrive, comme cv-qualification d'un type dans une liste de paramètres de modèle peut , en principe, donne un résultat "incompatible". Et même si dans ce cas il ne le fait pas, le compilateur n'a aucun moyen de le savoir.

Quoi qu'il en soit, est-il un moyen non-hackish pour effectuer cette conversion? Je me méfie d'utiliser reinterpret_cast pour tout ce que j'ai déjà été par des problèmes de type-punning avant. En outre, je ne peux pas utiliser de temporaires, car il s'agit d'un code critique pour les performances.

EDIT:

Voici ce que je fais. J'implémente une interface de conteneur personnalisée compatible avec std::unordered_map. Pour cette raison, son value_type doit être un pair <const key_type, mapped_type>. Pour une optimisation, j'ai besoin de stocker en interne les valeurs , sans const. Cependant, si je fais cela, je ne peux pas (sans reinterpret_cast) implémenter des itérateurs sur le conteneur, car ils doivent renvoyer des références aux valeurs et je n'ai que des références à ces paires non-const.

+0

Quel est votre cas d'utilisation prévu pour cela? J'ai du mal à voir comment cela serait utilisé. –

+0

Vous pouvez conserver deux telles structures et définir une fonction de conversion du moins const à plus const. – dirkgently

+0

@James McNellis: Je suppose qu'il a une fonction qui renvoie une paire et une autre qui prend une paire * –

Répondre

1

Ce n'est pas un casting, mais vous pouvez faire ce qui suit:

std::pair<int, int> x; 
std::pair<const int, int> y(x); 

Cela devrait fonctionner selon § 20.2.2/4.

+0

L'astuce est 'y.second 'doit se référer à la même variable que' x.deuxième'. Peut-être que 'std :: pair y (x.first, x.second)' pourrait fonctionner. –

0

Que diriez-vous ceci:

template< typename T1, typename T2 > 
struct ref_pair { 
public: 
    typedef const T1 first_type; 
    typedef T2 second_type; 

    ref_pair(first_type& f, second_type& s) : f_(f), s_(s) {} 

    first_type& first() {return *f_;} 
    second_type& second() {return *s_;} 
private: 
    first_type* f_; 
    second_type* s_; 
}; 

Je sais, c'est différent, ce sont des fonctions. Si vous êtes vraiment désespéré, vous pouvez transformer first et second en objets de type proxy qui retardent l'évaluation *f_ et *s_.
Cependant, à la fin, les utilisateurs peuvent toujours faire la différence.


Je pense que ce qui suit serait raisonnablement sûr et portable, bien que, bien sûr, avec reinterpret_cast rien est garanti:

std:::pair<const int,int>& rx = reinterpret_cast<std:::pair<const int,int>&>(x); 

Il se sent sale, cependant. Je vais maintenant me laver les mains.

+0

http://stackoverflow.com/questions/14272141/is-casting-stdpairt1-t2-const-to-stdpairt1-const-t2-const-safe –

Questions connexes