5

我有一个带有转换运算符的类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它会工作,但我的问题是很多已经存在和接收的 stl 函数std::basic_string<T>(例如,operator<<打印函数,或比较运算符,或许多其他函数.

我真的很希望能够像A使用std::string. 有没有办法做到这一点?

4

3 回答 3

2

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

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

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

于 2013-08-07T14:57:01.297 回答
2

我真的很希望能够像使用std::string. 有没有办法做到这一点?

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

struct A : public std::string {
};

但回想一下,std::string它没有virtual析构函数,因此不能多态使用。你被警告了!!!

Astr()是一个更好的解决方案,当你想将你传递A给一个采用std::basic_string<T>.

于 2013-08-07T15:09:23.747 回答
1

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

Gwill work的明确专业化。

G<char>(a);
于 2013-08-07T14:57:52.077 回答