Conversion Operator with Template Functions

I have a class with a conversion operator before std::string . It works great with everything except functions receiving std::basic_string<T> (templated on T ).

 #include <string> struct A{ operator std::string(){return std::string();} }; void F(const std::basic_string<char> &){} template<typename T> void G(const std::basic_string<T> &) {} int main(){ A a; F(a); // Works! G(a); // Error! return 0; // because otherwise I'll get a lot of comments :) } 

I get an error

 error: no matching function for call to 'G(A&)' note: candidate is: note: template<class T> void G(const std::basic_string<_CharT>&) 

Now I know that I can define G as a friend in structure A , and it will work, but my problem is with a lot of stl functions that already exist and get std::basic_string<T> (for example, the print function operator<< or comparison operators or many other functions.

I would really like to use A , as if it were std::string . Is there any way to do this?

+4
source share
3 answers

I would really like to use A, as if it were std::string . Is there any way to do this?

Yes, but are you sure you really want this? Decision:

 struct A : public std::string { }; 

but recall that std::string does not have a virtual destructor and therefore cannot be used polymorphically. You have been warned!

A str() is a much better solution and allows you to be explicit when you want to pass your A function to it using std::basic_string<T> .

+2
source

The compiler cannot do this far; you will either have to explicitly call the translation operator, or explicitly specify the template parameter:

 G(static_cast<std::string>(a)); G<char>(a); 

To understand why the compiler cannot perform both the user-defined conversion and the argument of the template argument, take this example:

 template<typename T> struct Number { Number(double n) {}; Number(int n) {}; }; struct A{ operator Number<double>(){return Number<double>(1.);} operator Number<int>(){return Number<int>(1);} }; template<typename T> void G(Number<T>& number) { } int main(){ A a; G(a); // What do I do ?! return 0; } 

What should the compiler do in this case?

+2
source

User-defined transformations are not taken into account when the template argument is output.

Explicit specialization G will work.

 G<char>(a); 
+1
source

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


All Articles