2015-05-30 7 views
10

Betrachten Sie den folgenden Code ein:nicht-statische Daten Memberinitialisierungsliste mit neuem Ausdruck

#include <map> 

template <typename T> 
struct X { 
    std::map<int, T>* storage = new std::map<int, T>(); 
}; 

int main() { 
    X<int> x; 
} 

Dies kompiliert auf clang 3.6.0, aber nicht auf gcc 5.1 kompilieren. Es würde jedoch kompilieren, wenn der Typ storage stattdessen std::vector<T>* (oder nur T*) wäre.

Ich bin ziemlich sicher, das ist ein Compiler Fehler auf gcc Teil (edit: ich es als 66344 vorgelegt), aber dachte, ich würde fragen, um sicher zu stellen: Gibt es einen Grund, das obige Beispiel soll nicht Kompilierung ?

gcc Compiler-Fehler:

main.cpp:5:51: error: expected ';' at end of member declaration  
    std::map<int, T>* storage = new std::map<int, T>();  
               ^ 

main.cpp:5:51: error: declaration of 'std::map<int, T> X<T>::T'  
main.cpp:3:11: error: shadows template parm 'class T'  
template <typename T>  
     ^

main.cpp:5:52: error: expected unqualified-id before '>' token  
    std::map<int, T>* storage = new std::map<int, T>();  
                ^ 
main.cpp:5:46: error: wrong number of template arguments (1, should be at least 2)  
    std::map<int, T>* storage = new std::map<int, T>();  
              ^

In file included from /usr/local/include/c++/5.1.0/map:61:0,  
       from main.cpp:1:  
/usr/local/include/c++/5.1.0/bits/stl_map.h:96:11: note: provided for 'template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map'  
    class map  
     ^
+0

Nur um sicher zu sein: Verwenden Sie 'gcc' oder' g ++ '? Das habe ich mal zu oft gemischt ... – atlaste

+0

@atlaste g ++ 4.9.2 kompiliert das auch nicht. –

+0

MSVC13 kompiliert es ohne Fehler. So scheint ein Fehler zu sein – Christophe

Antwort

3

Dies ist ein weiteres Beispiel für das Problem ist in Core issue 325 (siehe die "Notizen vom August 2011 Treffen", die ein sehr ähnliches Beispiel haben), nämlich dass das Komma im Template-Argument list verursacht einen Parse-Fehler, wenn der Compiler versucht festzustellen, wo das Ende des Ausdrucks ist.

Das Problem ist noch offen, aber der Konsens des Ausschusses ist, dass es gemacht werden sollte, um zu arbeiten (ich weiß nicht, was geändert wird, um es gültig zu machen, obwohl).

Clang hat eine Workaround für einige Zeit implementiert (vielleicht versuchsweise den Ausdruck analysieren und erneut versuchen, wenn es fehlschlägt) und Nathan Sidwell hat nur un-suspended the relevant G++ bug and assigned it to himself, also hoffe ich, er plant, es bald zu beheben.

+0

Kernproblem 325 scheint über Standardargumente zu sein – sp2danny

+0

@ sp2danny, lesen Sie weiter, siehe die "Notizen vom August 2011 Treffen", die ein sehr ähnliches Beispiel haben –

3

Interessant, sollte es IMO arbeiten.

Diesein kompilieren:

#include <map> 

template <typename T> 
struct X { 
    typedef std::map<int, T> mt; 
    mt *storage = new mt(); 
}; 

int main() { 
     X<int> x; 
} 

offenbar etwas schief geht mit der Erweiterung Template-Argument ...

Compile mit: beschrieben

g++ -o test test.cpp -std=c++11 
Verwandte Themen