https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37804
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |rejects-valid --- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> --- Here's the reduced form of the rejects-valid case from comment 6 namespace std { template <typename T> struct basic_string { template<typename U> friend struct vector; }; } std::basic_string<char> it; // injects std::vector<T> into global scope namespace std { template<typename U> struct vector { }; } using std::vector; f.cc:19:12: error: ‘vector’ is already declared in this scope using std::vector; ^ That seems slightly different, as it only misbehaves when std::vector is a template, i.e. this version compiles OK: namespace std { template <typename T> struct basic_string { friend struct foo; }; } std::basic_string<char> it; // does not inject std::foo namespace std { struct foo { }; } using std::foo; Curiously, although the error for the first example says vector has already been declared at global scope, it apparently refers to std::vector and yet is considered incomplete: namespace std { template <typename T> struct basic_string { template<typename U> friend struct bar; }; } std::basic_string<char> it; // injects std::bar<T> into global scope namespace std { template<typename U> struct bar { }; } bar<int> b; fr.cc:19:10: error: aggregate ‘std::bar<int> b’ has incomplete type and cannot be defined bar<int> b; ^