2010-12-06 23 views
4

Après avoir rejoint SO, je vois souvent ce type de syntaxe chaque fois que j'ouvre des sujets discutant des modèles. J'ai essayé de chercher sur google, mais en vain.syntaxe de modèle C++ complexe

template<typename T> 
char (&f(T[1]))[1]; //what is it? what is the use of '[]' brackets and the integer in it? 

template<typename T> 
char (&f(...))[2]; //not this either 

int main() { char c[sizeof(f<void()>(0)) == 2]; } // and this? 

D'ici: SFINAE with invalid function-type or array-type parameters?

S'il vous plaît expliquer les 3 lignes où je l'ai mis des commentaires. Je veux particulièrement comprendre la syntaxe. Pouvons-nous utiliser une telle syntaxe dans les modèles uniquement?

Répondre

4

Les deux suivantes sont équivalentes

// 1 
template<typename T> 
char (&f(...))[2]; 

// 2 
typedef char rettype[2]; 
template<typename T> 
rettype &f(...); 

Vous avez peut-être vu ce modèle avant avec des pointeurs de fonction

char (*XXX)(); 

remplacer maintenant juste le () avec [N] pour créer un tableau au lieu d'une partie de la fonction , et remplacez * par & pour créer une référence au lieu d'un pointeur et remplacez le XXX par un déclarateur de fonction. Ensuite, vous obtenez une fonction qui renvoie une référence à un tableau de taille N.


Vous pouvez regarder dans man signal, qui contient une déclaration de fonction de la même tapé. Si vous prenez la declarator intérieure qui déclare effectivement la fonction, vous obtenez le même schéma

void (* signal(int sig, void (*func)(int)))(int); 
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ take out that 

Il renvoie un pointeur vers une fonction qui prend une int et retourne void, comme décrit dans cette page de manuel.


Ce qui suit est juste une façon de donner une erreur du compilateur si certaines conditions ne sont pas satisfaits. Si le test foo == 2 s'avère être false, le tableau créé est de taille nulle, ce qui est illégal dans C++, et va gagner une erreur de temps de compilation. Si elle est évaluée à true, rien ne se passe à l'exception du tableau déclaré.

char c[some silly condition here]; 
+0

bonne explication, merci. Si cette condition stupide crée un tableau de taille nulle, alors pourquoi avez-vous mis cette condition? –

+0

Parce que le but est d'utiliser l'invalidité de la taille du tableau pour empêcher la compilation d'un morceau particulier de code - par exemple, une instanciation de certains modèles pour des types particuliers qui doivent être gérés spécialement. –

+0

@Pointer: c'est un concept connu sous le nom de "compile time assert". Le "normal" 'assert()' vérifie une condition booléenne à l'exécution. Avec cette méthode, vous pouvez vérifier une condition booléenne au moment de la compilation. Par exemple, 'char c [CHAR_BIT == 8]' rend explicite que votre programme ne peut pas gérer les compilateurs qui ont 'CHAR_BIT == 9' – MSalters