具有模板函数的转换运算符

conversion operator with template functions

本文关键字:转换 运算符 函数      更新时间:2023-10-16

我有一个类,它带有到std::string的转换运算符。它适用于除接收std::basic_string<T>(在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 :)
}

我收到的错误是

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

现在,我知道我可以将G定义为结构A中的朋友,它会起作用,但我的问题是许多已经存在并接收std::basic_string<T>的stl函数(例如,operator<<打印函数、比较运算符或许多其他函数)。

我真的希望能够像使用std::string一样使用A。有办法做到这一点吗?

我真的希望能够像使用std::string一样使用A。有办法做到这一点吗?

是的,但你确定你真的想要这个吗?解决方案是:

struct A : public std::string {
};

但请记住,std::string没有virtual析构函数,因此不能多晶型使用你已经被警告了

str()是一个更好的解决方案,当您想将A传递给采用std::basic_string<T>的函数时,它允许您显式。

编译器不能推断出那么远;您要么必须显式调用强制转换运算符,要么显式指定模板参数:

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

为了理解为什么编译器不能同时进行用户定义的转换和模板参数推导,让我们举一个例子:

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;
}

在这种情况下编译器应该怎么做?

执行模板参数推导时,不考虑用户定义的转换。

G的明确专业化将起作用。

G<char>(a);