将函数模板限制为特定类型
Restrict function template to specific types?
我想制作一个函数,使字符串连接变得容易。假设我有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
函数。
如果我像这样为A
实现std::to_string
:
namespace std {
std::string to_string(A & a)
{
return "a = " + std::toString(a.a) + ", b= " + std::to_string(a.b);
}
}
上面的例子会起作用。
问题是,如果我尝试像这样连接两个字符串,这将不起作用:cout << s + std::string{"blabla"};
,因为std::string
没有std::to_string
;
我认为,如果我可以以某种方式将operator+
函数限制为具有std::to_string
的类型,那么这个问题就可以解决。
有可能吗?
现在的典型答案是这样的。使用一个额外的模板参数来定义函数,如果由表达式构造的伪类型不存在,该参数将使函数被忽略。
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的语言功能。
相关文章:
- 仅在函数模板中为那些定义了函数的类型执行函数
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 函数模板返回类型
- 特定类型的模板函数的专用化
- 在实例化之前推断函数模板的返回类型
- 函数模板签名中忽略的成员类型def 的访问说明符
- 实例化多种类型的成员函数模板
- 使用函数模板推导返回类型
- 重载模板<类型名...>类的函数模板
- 将函数类型作为模板参数传递不会编译
- 专用于类型集的函数模板
- async中没有匹配的函数(模板中未解析的类型)
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- 为什么重载的函数模板顺序对基本类型很重要
- 没有函数模板的实例"max"与参数列表参数类型匹配(int、int)
- 模板函数重载(泛型类型与模板模板类型)选择正确的重载
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- 具有指针数据类型的非类型函数模板参数
- C++模板基类的非类型函数模板的 using 声明
- 非类型函数模板参数