2016-05-09 22 views
17

Saremo aggiornamento a VS2015 presto, e ho trovato questo nella frazione lista delle modifiche:Visual Studio 2015: è consentita una serie di puntatori const?

elementi const

Il C++ standard ha sempre proibito contenitori di elementi const (come vettore o set) . Visual C++ 2013 e versioni precedenti hanno accettato tali contenitori. Nella versione corrente, tali contenitori non riescono a compilare .

source

Mi chiedevo se qualcuno sa se questo vale anche per un set. So che una mappa può ancora contenere puntatori const come chiavi, poiché sono comunque costanti.

Un esempio:

std::set<const QObject*> 

Posso ancora fare questo? Non penserei, secondo il post sul sito di Microsoft.

+16

'const T *' e 'T * non const' la stessa cosa. –

+2

La citazione dice letteralmente che si applica al set. Tuttavia, il tuo codice non ha molto a che fare con la citazione in modo da essere al sicuro :) –

+1

La confusione è rafforzata dallo stile nobilmente intenzionale ma fuorviante che omette lo spazio prima dell'asterisco (o la e commerciale su un riferimento) . Scrivere 'const QObject *' suggerisce visivamente che '*' si lega a QObject più stretto di 'const'. Spostare il 'const' non aiuta:' QObject const * '. È come scrivere 'return a * x + b * y;'. –

risposta

26

const QObject* è un puntatore aconst QObject. Il puntatore stesso è ancora modificabile. const QObject* const renderebbe il puntatore stesso const.

Poiché l'articolo di Microsoft parla di oggetti const, che const QObject* è non, l'esempio va bene.

4

So che una mappa può ancora contenere puntatori const come chiavi, poiché sono comunque costanti.

std::set<T* const> è sempre stato non valido e std::map<int* const, int* const> s; è sempre stato valido. Il motivo è perché l'allocatore per std::set è std::allocator<Key>, mentre l'allocatore per std::map è std::allocator<std::pair<const Key, T>>. Per definizione, un std::allocator<const T> è mal formato. Se si desidera che il codice map a fallire, si dovrà specificare un allocatore personalizzato come questo:

int i = 42; 
int* const j = &i; 
std::map<int* const, int* const, 
    std::allocator<const std::pair<int* const, int* const>>> s{{j, j}};