Consider the following code:
#include <map>
template <typename T>
struct X {
std::map<int, T>* storage = new std::map<int, T>();
};
int main() {
X<int> x;
}
This compiles on clang 3.6.0, but fails to compile on gcc 5.1. It would compile, however, if the type of storage
were instead std::vector<T>*
(or just T*
).
I'm fairly certain this is a compiler bug on gcc's part (edit: I submitted it as 66344), but thought I'd ask to make sure: is there any reason the above example shouldn't compile?
gcc compile error:
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
^
This is another example of the problem described in Core issue 325 (see the "Notes from the August, 2011 meeting" which have a very similar example), namely that the comma in the template argument list causes a parse failure when the compiler tries to determine where the end of the expression is.
The issue is still open, but the consensus of the committee is that it should be made to work (I don't know what will be changed to make it valid though).
Clang has implemented a workaround for some time (maybe tentatively parsing the expression and retrying if it fails) and Nathan Sidwell has just un-suspended the relevant G++ bug and assigned it to himself so I hope he plans to fix it soon.
Interesting, it should work IMO.
This one does compile:
#include <map>
template <typename T>
struct X {
typedef std::map<int, T> mt;
mt *storage = new mt();
};
int main() {
X<int> x;
}
Apparently something goes wrong with the template argument expansion...
Compile with:
g++ -o test test.cpp -std=c++11
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With