为什么我的SFINAE开关不工作?

时间:2017-03-08 10:37:27

标签: c++ sfinae c++98

以下是我想要实现的目标:

f(3)

try it on coliru

我希望拨打"sfinae"的电话可以返回f<int>(3)。我做错了什么?

对于要调用的第一个版本,我必须手动调用{{1}}。我很困惑。

1 个答案:

答案 0 :(得分:4)

以下内容可行:

template <typename T>
const char* f_impl(
    typename enable_if<std::numeric_limits<T>::is_integer, T>::type t) {
  return "sfinae";
}

template <typename T>
const char* f_impl(
    typename enable_if<!std::numeric_limits<T>::is_integer, T>::type t) {
  return "";
}

template <typename T>
const char* f(T t) {
  return f_impl<T>(t);
}

on coliru

如果您按如下方式调用f,原始代码将有效:

std::cout << f<int>(3) << "\n";
std::cout << f<double>(3.0) << "\n";

这是因为第一个f (SFINAE one)永远无法推断T,因为它位于non-deduced context内。这意味着除非您明确指定模板参数,否则永远不会调用它!

通过添加推导出T然后明确调用f_impl的间接层,您可以轻松获得扣除和SFINAE。

在C ++ 11中,您甚至不需要SFINAE:

const char* f_impl(std::true_type)  { return "sfinae"; }
const char* f_impl(std::false_type) { return ""; }

template<typename T> const char* f(T t) 
{ 
    return f_impl(std::is_integral<T>{}); 
}