I am trying to define a full specialization of std::basic_string< char, char_traits<char>, allocator<char> >
which is typedef'd (in g++) by the <string>
header.
The problem is, if I include <string>
first, g++ sees the typedef as an instantiation of basic_string
and gives me errors. If I do my specialization first then I have no issues.
I should be able to define my specialization after <string>
is included. What do I have to do to be able to do that?
My Code:
#include <bits/localefwd.h>
//#include <string> // <- uncommenting this line causes compilation to fail
namespace std {
template<>
class basic_string< char, char_traits<char>, allocator<char> >
{
public:
int blah() { return 42; }
size_t size() { return 0; }
const char *c_str() { return ""; }
void reserve(int) {}
void clear() {}
};
}
#include <string>
#include <iostream>
int main() {
std::cout << std::string().blah() << std::endl;
}
The above code works fine. But, if I uncomment the first #include <string>
line, I get the following compiler errors:
blah.cpp:7: error: specialization of ‘std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ after instantiation
blah.cpp:7: error: redefinition of ‘class std::basic_string<char, std::char_traits<char>, std::allocator<char> >’
/usr/include/c++/4.4/bits/stringfwd.h:52: error: previous definition of ‘class std::basic_string<char, std::char_traits<char>, std::allocator<char> >’
blah.cpp: In function ‘int main()’:
blah.cpp:22: error: ‘class std::string’ has no member named ‘blah’
Line 52 of /usr/include/c++/4.4/bits/stringfwd.h
:
template<typename _CharT, typename _Traits = char_traits<_CharT>,
typename _Alloc = allocator<_CharT> >
class basic_string;
As far as I know this is just a forward delcaration of the template, NOT an instantiation as g++ claims.
Line 56 of /usr/include/c++/4.4/bits/stringfwd.h
:
typedef basic_string<char> string;
As far as I know this is just a typedef, NOT an instantiation either.
So why are these lines conflicting with my code? What can I do to fix this other than ensuring that my code is always included before <string>
?
You are only allowed to specialize a standard library if the specialization depends on a user-defined name with external linkage. char
doesn't meet this requirement and you are getting undefined behaviour.
This is specified in 17.4.3.1 [lib.reserver.names]/1.
The particular error that you are getting is because your implementation already instantiates the template that you are trying to specialize and, if you provide a specialization for any template, it must be before the template is ever instantiated with the parameters for which you want to provide the specialization.
14.7.3 [temp.expl.spec]/6
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