我想创建一个易于连接字符串的函数。
假设我有struct A
:
struct A {
int a;
double b;
}
现在我要像这样打印:
A a = {1, 2.0};
cout << someString + string{"dsdassa"} + a;
或者像这样连接字符串:
string s{"das"};
string s2 = s + A{1, 2.0f};
所以我做这样的功能:
template <typename T>
std::string operator+(std::string & lhs, T && t)
{
std::cout<< std::endl << "LOG" << '\t' << "operator+(std::string & lhs, T && t)" << std::endl;
std::string neww(lhs);
neww += ' ';
neww += std::to_string(t);
return neww;
}
对于此功能,工作类型T
必须具有std::to_string
功能专用。
如果我为std::to_string
实施A
,请执行以下操作:
namespace std {
std::string to_string(A & a)
{
return "a = " + std::toString(a.a) + ", b= " + std::to_string(a.b);
}
}
上面的例子可行。
问题在于,如果我尝试连接2个这样的字符串,那么这将不起作用:cout << s + std::string{"blabla"};
因为std::to_string
没有std::string
;
我认为如果我以某种方式将operator+
函数限制为具有std::to_string
的类型,就可以解决这个问题。
有可能吗?
答案 0 :(得分:3)
这些天的典型答案是这样的。使用额外的模板参数定义函数,如果从表达式构造的虚拟类型不存在,将使函数被忽略。
template <typename T, typename = decltype(std::to_string(std::declval<T>()))>
std::string operator+(std::string & lhs, T && t)
{
...
}
它可以通过它做你想要的更精致。
另一个更优雅的语法是
template <typename T>
auto operator+(std::string & lhs, T && t) -> decltype(std::to_string(t))
{
...
}
这利用了一种名为SFINAE的语言功能。