函式模板中的尾隨 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
上有一個模板堆疊的硬編譯錯誤。