Подтвердить что ты не робот

Инициализация нестатических данных с новым выражением

Рассмотрим следующий код:

#include <map>

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

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

Это компилируется на clang 3.6.0, но не компилируется на gcc 5.1. Однако он скомпилировал бы, если бы тип storage был вместо std::vector<T>* (или просто T*).

Я уверен, что это ошибка компилятора на gcc part (edit: Я отправил его как 66344), но думал, что я 'd спросить, чтобы убедиться: есть ли какая-либо причина, которую приведенный выше пример не должен компилировать?

Ошибка компиляции gcc:

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    
           ^
4b9b3361

Ответ 1

Это еще один пример проблемы, описанной в Основной вопрос 325 (см. "Заметки от собрания августа 2011 года", которые имеют очень аналогичный пример), а именно, что запятая в списке аргументов шаблона вызывает сбой анализа, когда компилятор пытается определить, где находится конец выражения.

Вопрос по-прежнему остается открытым, но консенсус комитета заключается в том, что его следует заставить работать (я не знаю, что будет изменено, чтобы сделать его действительным, хотя).

Clang внедрил обходное решение в течение некоторого времени (возможно, предварительное синтаксическое разложение выражения и повторная попытка, если он терпит неудачу), а Nathan Sidwell просто не приостановил соответствующую ошибку g++ и назначил его себе, поэтому я надеюсь, что он скоро исправит его.

Ответ 2

Интересно, что он должен работать с ИМО.

Этот компилируется:

#include <map>

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

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

По-видимому, что-то не так с расширением аргумента шаблона...

Скомпилировать с помощью:

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