2011-08-06 1 views
2

Supposons une pa variable est toujours déclarée comme l'une des deux façons:Peut-on créer une instruction IF qui détermine si une variable a été déclarée comme un pointeur en C/C++

double * pa

OU

deux pa

Peut-on créer une instruction IF qui fait le

suivant IF (pa est un pointeur) {pa [0] = 1 }

ELSE {pa = 1}

EDIT:

S'il vous plaît voir How to find out if a pointer array has been filled in C++/C pour la question de suivi

+2

Cela peut probablement être fait à la compilation avec des modèles. La question est: pourquoi? Vous devriez faire ceci * partout * que vous avez l'intention d'utiliser 'pa'. Quelle situation nécessite cela? –

+3

La notion de C++ étant un langage dynamique est intéressante. Je veux m'abonner à votre lettre d'information. –

+0

Qu'est-ce que vous ** essayez vraiment de faire? Les façons dont 'pa' est déclaré ailleurs dans le programme sont totalement sans rapport avec la façon spécifique dont il est déclaré dans le contexte de l'instruction if. –

Répondre

2

Pas directement, non. Supposons qu'il y ait une façon de faire, quelque chose comme

if (__IS_POINTER(pa) { 
    pa[0] = 1; 
} 
else { 
    a = 1; 
} 

Qu'advient-il si pa n'est pas un pointeur? Vous avez toujours cette instruction pa[0] = 1; dans votre programme, et c'est illégal, donc le compilateur va rejeter votre programme.

Vous pouvez, en principe, être en mesure de faire un test de compilation:

#if __pa_IS_A_POINTER 
pa[0] = 1; 
#else 
a = 1 
#endif 

mais la puissance du préprocesseur C++ est très limité; il n'a aucun moyen de tester le type d'une variable ou d'une expression.

Si vous aviez cette capacité, que feriez-vous avec? Dites-nous quel est votre objectif réel.

+0

OK Je comprends cette réponse. Je vais ajouter une nouvelle question qui explique mon problème différemment. – gamma123

+0

Cela peut être fait cependant. Voir toute implémentation de 'type_traits', comme Boost's, qui a un template' is_pointer'. :) mais ce que l'OP demande n'est pas possible pour les raisons que vous dites. – jalf

0

En C++ 0x vous pouvez, en utilisant des caractères de type et decltype:

#include <type_traits> 

if (std::is_pointer<decltype(x)>::value) 
{ 
    /* ... */ 
} 

En C++ 98/03 vous n'avez pas decltype, mais maintenant que vous auriez à expliquer comment vous pourriez avoir un variable sans connaître son type. Si vous avez ce type, vous pouvez utiliser le même trait de type:

#include <tr1/type_traits> 
template <typename T> void bogus(T x) // T could be a pointer or not 
{ 
    if (std::tr1::is_pointer<T>::value) { /*...*/ } 
} 

Vous pouvez également définir simplement votre propre classe de trait si vous n'avez pas ou si vous voulez utiliser TR1:

template <typename> struct is_pointer { static const bool value = false; }; 
template <typename T> struct is_pointer<T*> { static const bool value = true; }; 
6

les bases du C++ 0x std::is_pointer pourrait fonctionner:

template <typename T> 
struct is_pointer_helper { 
    static const bool value = false; 
}; 

template <template T> 
struct is_pointer_helper<T*> { 
    static const bool value = true; 
}; 

pour cet exemple, nous ne voulons pas avoir à utiliser le type, donc nous avons besoin d'une déduction argument modèle:

template <typename T> 
bool is_pointer(const T &) { 
    return is_pointer_helper<T>::value; 
} 

Et nous avons fini:

if (is_pointer(pa)) { 
    pa[0] = 1; 
} else { 
    pa = 1; 
} 

MAIS, notez que ce code encore ne compilera pas moins pa[0] = 1 et pa = 1 sont les deux expressions valides (et pour ne double ni double* sont-ils tous les deux valides - Si vous définissez à 0 alors les deux seraient valides pour double*, mais toujours seulement la seconde pour double). Alors sans doute ce que vous voulez est pas explicite « si » test, mais une fonction surchargée:

template <typename T> 
void set_thingy(T &t) { 
    t = 1; 
} 

template <typename T> 
void set_thingy(T *pt) { 
    set_thingy(*pt); 
} 

set_thingy(pa); 

Ou, puisque pa est toujours double ou double*, il n'y a pas besoin de se concentrer sur le fait que l'on est un pointeur et l'autre ne l'est pas, ils ne sont que deux types différents que nous devons traiter différemment.Donc, pas besoin de modèles:

void set_thingy(double &d) { d = 1; } 
void set_thingy(double *p) { *p = 1; } 

set_thingy(pa); 
+0

Les deux versions doivent être compilables même si une seule branche est toujours exécutée. Votre code ne compilerait pas. – Nawaz

+2

@Nawaz: oui, ma réponse le dit déjà. –

+0

Oui. Maintenant, ça dit ça. :-) – Nawaz

Questions connexes