2016-10-08 1 views
0

Le code C++ suivant:typedef erreur jetant même avec typename mot-clé

template<typename State> 
class Node 
{ 
public: 
    typedef typename State::Move Move; 
... 
} 

dit:

spécificateur de type manquant - int pris en charge. Note: C++ ne prend pas en charge par défaut-int

Je recherchais le message d'erreur et tout le monde suggère d'ajouter typename mot-clé à la typedef ligne, qui dans mon cas est déjà là. Quoi d'autre suis-je censé faire?

+0

Etes-vous sûr que c'est la ligne avec l'erreur? – tkausl

+0

@tkausl: Au moins dans ce double-clic, le message m'amène à cette ligne. – dotNET

+0

Compile pour moi: http://cpp.sh/2lqe5 – tkausl

Répondre

0

Merci à tous ceux qui ont aidé. Le problème était en effet ailleurs. Permettez-moi de vous expliquer:

En C#, nous utilisons des médicaments génériques (qui sont des équivalents rugueux du système de modèles de C) dans la définition de classe et peuvent appliquer des contraintes sur les:

class Node<T> where T:SomeClass { ... } 

qui nous permet d'instancier des objets de type T à l'intérieur de cette classe. Ces objets auront tous les membres de SomeClass automatiquement. Vous obtenez également un bon intellisense en bonus. Une grande chose à propos de ce système est que l'intégrité de cette classe peut être vérifiée au moment de la compilation sans que nous ayons à instancier un objet de type Node<T>.

[avertissement: Ce qui suit est ma compréhension. Corrige moi si je me trompe.]

C++ ne fonctionne pas de cette façon. C++ vous permettra d'accéder à n'importe quel paramètre de template (dans mon cas c'était State::Move). La classe modélisée en elle-même ne peut/ne peut pas garantir que le paramètre template aura réellement un membre nommé Move. Ce n'est que lorsque vous instanciez un objet de classe modélisée, tel que Node<SomeType> x;, que SomeType doit contenir un membre nommé Move et renvoie une erreur si ce n'est pas le cas.

Dans mon problème, j'instanciation d'un objet de Node et de la transmettre un int comme paramètre de modèle, ce qui n'a évidemment aucun membre nommé Move, il me plaignais (pointant malheureusement à un endroit très mal, mais c'est une autre histoire). Le remplacer par le type approprié a corrigé l'erreur pour moi.

Hope this helps quelqu'un sur la route.

+0

Si vous êtes vraiment intéressé par les problèmes sous-jacents aux templates C++, dont la puissance n'a pas été conçue mais découverte (sic!) Pour aller bien au-delà de "container of T", alors cherchez "C++ concepts" dans Google. Les concepts n'ont pas encore atteint le standard C++, mais je suppose qu'ils rendraient les problèmes comme celui-ci beaucoup plus faciles à détecter et à résoudre. –

+0

@ChristianHackl: Il suffit de lire la rubrique Concepts C++ sur le wiki. Cette chose semble être ce que les génériques C# offrent déjà. non? c'est-à-dire que les contraintes de paramètres, la déduction de type sont déjà disponibles en C# (et VB.NET). Ou est-ce plus que ça? – dotNET

+0

Sans être un expert sur les génériques C#, je dirais que la différence majeure est que les contraintes génériques de C# sont limitées au paradigme orienté objet. Par exemple, avec votre 'where T: SomeClass', vous avez réellement besoin d'un type de base' SomeClass' quelque part et vous avez besoin de vos arguments de type pour en dériver. Ce n'est pas le cas avec les concepts, ou avec les modèles en général. Par exemple, un concept pourrait être utilisé pour indiquer explicitement que la fonction de modèle 'void f (T)' est limitée à 'T' avec une fonction membre' foo', sans avoir besoin d'une classe de base 'HasFooOperation'. –