【问题标题】:Why is my SFINAE switch not working?为什么我的 SFINAE 开关不工作?
【发布时间】:2017-03-08 10:37:27
【问题描述】:

这是我想要实现的 MCVE:

#include <limits>
#include <iostream>

// enable_if (I'm stuck with a c++98 compiler)
template<bool B, class T = void> struct enable_if {};
template<class T>                struct enable_if<true, T> { typedef T type; };

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

// test
int main()
{
    std::cout << f(3) << "\n"; // returns an empty string
    std::cout << f(3.0) << "\n"; // returns an empty string
}

(try it on coliru)

我期待对f(3) 的调用返回"sfinae"。我做错了什么?

要调用第一个版本,我必须手动调用f&lt;int&gt;(3)。我很困惑。

【问题讨论】:

    标签: c++ sfinae c++98


    【解决方案1】:

    以下将起作用:

    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 那个) 永远无法推断出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>{}); 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 1970-01-01
      相关资源
      最近更新 更多