函数模板中的尾随 decltype
Version >= C++ 11
约束函数之一是使用尾随 decltype
来指定返回类型:
namespace details {
using std::to_string;
// this one is constrained on being able to call to_string(T)
template <class T>
auto convert_to_string(T const& val, int )
-> decltype(to_string(val))
{
return to_string(val);
}
// this one is unconstrained, but less preferred due to the ellipsis argument
template <class T>
std::string convert_to_string(T const& val, ... )
{
std::ostringstream oss;
oss << val;
return oss.str();
}
}
template <class T>
std::string convert_to_string(T const& val)
{
return details::convert_to_string(val, 0);
}
如果我用一个可以调用 to_string()
的参数调用 convert_to_string()
,那么我有两个可行的 details::convert_to_string()
函数。首先是首选,因为从 0
到 int
的转换是比从 0
到 ...
的转换更好的隐式转换序列
如果我用一个我无法调用 to_string()
的参数调用 convert_to_string()
,那么第一个函数模板实例化会导致替换失败(没有 decltype(to_string(val))
)。结果,该候选者从过载集中移除。第二个函数模板是不受约束的,因此它被选中,我们改为通过 operator<<(std::ostream&, T)
。如果那个是未定义的,那么我们在线 oss << val
上有一个模板堆栈的硬编译错误。