2013-03-08 4 views
11

In C++, è possibile iniziare un nome di classe con una cifra ? Ad esempio,Puoi iniziare un nome di classe con una cifra numerica?

template <class T> class 2DArray { 

public: 
    // 1D ARRAY CLASS 
    class 1DArray { 
    public: 
     1DArray() { Create(); } 
     1DArray(iterator arr) : array1d_(arr) { } 
     explicit 1DArray(size_type cols, const T& t = T()) { Create(cols, t); } 
     1DArray(const 1DArray& arr) { Create(arr.begin(), arr.end()); } 
     1DArray& operator=(const 2DArray&); 
     ~1DArray() { Uncreate(); } 

     T& operator[](size_type n) { 
      return array1d_[n]; 
     } 
     const T& operator[](size_type n) const { 
      return array1d_[n]; 
     } 
} 
+0

potresti avere le cifre numeriche in fondo al nome della classe ... –

+1

Rinomina in Array, dato che è di default .. una dimensione. Quindi se hai una 2 dimensioni, chiamala Array2D. – Rapptz

risposta

24

Regole per identificatori in C++ sono:

  1. Non può iniziare con un numero
  2. può essere composto da lettere, numeri, sottolineano, i nomi dei personaggi universali e implementazione definito caratteri
  3. Non può essere un keyword.

Le sezioni del C++ draft standard che copre questo sono 2.11identificatori che include la seguente grammatica:

identifier: 
    identifier-nondigit   <- Can only start with a non-digit 
    identifier identifier-nondigit <- Next two rules allows for subsequent 
    identifier digit    <- characters to be those outlined in 2 above 
identifier-nondigit: 
    nondigit      <- a-z, A-Z and _ 
    universal-character-name 
    other implementation-defined characters 
[...] 

e 2.12Parole spiega tutte le identificatore riservato per l'uso come parole chiave.

Infine, i seguenti nomi sono riservati:

  1. nomi che contengono una doppia sottolineatura __, o iniziare con un trattino basso seguito da una lettera maiuscola (come _Apple) in qualsiasi ambito,
  2. Nomi che iniziano con un carattere di sottolineatura nello spazio dei nomi globale (come _apple nello spazio dei nomi globale) sono riservati.

La sezione che si occupa di questo nel progetto di norma è 17.6.4.3.2. Siamo in grado di trovare una spiegazione razionale per il motivo per cui queste sono riservati da Rationale for International Standard—Programming Languages—C che dice:

[...] Questo dà uno spazio dei nomi per la scrittura delle numerose macro e funzioni dietro quinte del non-esterni una biblioteca ha bisogno di fare il suo lavoro correttamente [...]

In C++ vale questo anche per name mangling come questo example spettacoli.


Note

  • 1.caratteri universali ammessi

I personaggi universali che sono ammessi è coperto in Annex E.1:

E.1 intervalli di caratteri consentiti [charname.allowed]

00A8, 00AA, 00AD,

00AF, 00B2-00B5, 00B7-00BA, 00BC-00BE, 00C0-00D6, 00D8-00F6, 00F8-00FF

0100-167F, 1681-180D, 180F-1FFF 200B-200D, 202A-202E, 203F-2040, 2054,

2060-206F 2070-218F, 2460-24FF, 2776-2793, 2C00-2DFF, 2E80 -2FFF

3004-3007, 3021-302F, 3031-303F

3040-D7FF F900-FD3D, FD40-FDCF,

FDF0-FE44, FE47-FFFD

10000-1FFFD , 20000-2FFFD, 30000-3FFFD, 40000-4FFFD, 50000-5FFFD, 60000-6FFFD, 70000-7FFFD, 80000-8FFFD, 90000-9FFFD, A0000-AFFFD, B0000-BFFFD, C0000-CFFFD, D0000-DFFFD, E0000-EFFFD

+0

Questo è vero anche per qualsiasi linguaggio simile a C, o per lo meno quasi tutto. –

+2

Chiarificazione: contenere un doppio trattino basso o iniziare con un trattino basso seguito da una lettera maiuscola, oppure iniziare con un trattino basso nello scope globale. – chris

+0

@chris Grazie per il chiarimento, modificato il mio post. –

3

La risposta semplice è no. Per esempio, perché non chiamarlo OneDArray?

+2

È brutto e stai risolvendo il problema sbagliato. Invece di sostituire la cifra con qualcos'altro, perché non cambiare il nome in "Array1D"? – jv110

+0

Ma in entrambi i casi, questa risposta non è utile. – jv110

1

nomi in C++ deve iniziare con una 'lettera', dove lettera è tutta la parte superiore e inferiore caso 'AZ, a-z'. '_' conta anche come 'lettera'. Può quindi essere seguito da qualsiasi combinazione di lettere e cifre.

+0

Quindi _2DArray dovrebbe essere a posto? – Cindeselia

+1

@Cindeselia dipende, qualsiasi nome nel namespace globale che inizia con '_' è riservato e non dovrebbe essere usato. Questo thread precedente chiarisce Vs. globali spazi dei nomi non globali nel caso in cui non sei sicuro http://stackoverflow.com/questions/10269012/global-scope-vs-global-namespace –

+1

@Cindeselia Questo thread precedente suggerisce di non utilizzare i trattini di sottolineatura nei nomi solo per sicuro http://stackoverflow.com/questions/224397/why-do-people-use-double-underscore-so-much-in-c –

4

Dal momento che, a sorpresa, non sono riuscito a trovare una versione duplicata o più generale di questa domanda, ecco una risposta basata su ciò che dice lo standard (C++ 11).

Prima di tutto, dal § 9/1, un nome di classe è un identificatore (o un semplice-template-id nel caso di una specializzazione modello, ma un semplice -template-id è composto anche da identificatori).

§2.11 definisce l'identificativo valido.E prima introduce alcuni concetti di base:

Un cifre è uno di questi: 0 1 2 3 4 5 6 7 8 9
Un tranne le cifre è uno di questi: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
A universale caratteri-name è una sequenza di tipo \unnnn o \Unnnnnnnn (dove ogni n è una cifra esadecimale)

The standard quindi definisce un identificatore -tranne le cifre come

  • o un tranne le cifre
  • o un universale caratteri nome
  • o un carattere speciale definito dall'implementazione (& ddagger;)

Infine, identificatore è definito in modo ricorsivo come

identificatore:
    identificatore-tranne le cifre
    identificatore   identificatore-tranne le cifre
    identificatore   cifre

Riepilogo: In altre parole, un identificatore deve iniziare con un carattere alfabetico (non numerico!), Che può essere seguito da qualsiasi cosa composta da caratteri alfanumerici, caratteri di sottolineatura e riferimenti a caratteri simili a \unnnn. Qualsiasi altra cosa è specifica per l'implementazione.


(& ddagger;) Se qualcuno sono supportati dipende dal compilatore, e li utilizzano in genere significa perdere la portabilità ad altri compilatori o versioni del compilatore.

+2

Grazie per il riassunto chiaro, anche se non sono sicuro del motivo per cui è stato sorprendente. Se avessi trovato la risposta su Google o Stack Overflow, non avrei chiesto. Anche lo standard parlato ricorsivo sfugge al mio semplice cervello; la mia comprensione è arrivata fino a quando il nome della classe è un identificatore, e quindi la parte identificatore-identificatore-non-conduttore non ha senso per me. – Cindeselia

+0

@Cindeselia Sì, certo. Non sono stato sorpreso dal fatto che tu abbia fatto la domanda. Sono sorpreso dal fatto che nessuno lo abbia mai chiesto prima. – jogojapan

+0

@Cindeselia Oh, per quanto riguarda la definizione di _identifier_: è necessario leggere ogni riga come alternativa. Quindi un _identifier_ è o un _identifier-nondigit_, o _identifier_ seguito da _identifier-nondigit_ o _identifier_ seguito da _digit_. Quindi, _identifier_ si presenta nella sua propria definizione e può essere ricorsivamente sostituito con ulteriori istanze di quella definizione. Qualsiasi sequenza da cui potresti formarti inizierà sempre con un _identifier-non-digit_. – jogojapan