Std :: basic_string full specialization (g ++ conflict)

I am trying to define the full specialization of std::basic_string< char, char_traits<char>, allocator<char> > , which is the typedef'd (in g ++) header of <string> .

The problem is that if I include <string> , first g ++ sees typedef as an instance of basic_string and gives me errors. If I do my specialization first, I have no problem.

I will be able to determine my specialization after the inclusion of <string> . What do I need to do to do this?

My code is:

 #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 is working fine. But, if I uncomment the first line of #include <string> , 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 from /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 forward partitioning of the template, not an instance, as g ++ claims.

Line 56 from /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 instance.

So why do these lines contradict my code? What can I do to fix this, except that my code is always included before <string> ?

+4
source share
2 answers

You are allowed to specialize the standard library if the specialization depends on the name of the user with external communication. char does not meet this requirement and you get undefined behavior.

This is specified in 17.4.3.1 [lib.reserver.names] / 1.

The specific error you get is that your implementation is already creating a template that you are trying to highlight, and if you provide specialization for any template, it must be before the template is created with the parameters for which you want provide specialization.

14.7.3 [temp.expl.spec] / 6

+10
source

Generally, you should not define or specialize anything other than a feature class in the std namespace, and you certainly should not try to change the definition of the type underyling std :: string.

Instead of specializing basic_string, you should create your own character data type in your own namespace, then you should specialize in std :: char_traits for this type (but nothing else in the std namespace), and then you should make a convenient typedef for basic_string created using these types in your own namespace (not in the std namespace, which belongs to the C ++ standard and should not be changed by users).

0
source

Source: https://habr.com/ru/post/1307826/


All Articles