SFINAE和std :: numeric_limits

时间:2018-11-02 18:40:35

标签: c++ templates sfinae enable-if

我正在尝试编写一个流类,分别处理数字和非数字数据。有人可以向我解释为什么此代码无法编译吗?

#include <iostream>
#include <cstdlib>

#include <type_traits>
#include <limits>

class Stream
{
public:
    Stream() {};

    template<typename T, typename std::enable_if_t<std::numeric_limits<T>::is_integer::value>>
    Stream& operator<<(const T& val)
    {
        std::cout << "I am an integer type" << std::endl;
        return *this;
    };

    template<typename T, typename std::enable_if_t<!std::numeric_limits<T>::is_integer::value>>
    Stream& operator<<(const T& val)
    {
        std::cout << "I am not an integer type" << std::endl;
        return *this;
    };
};

int main()
{
    Stream s;
    int x = 4;
    s << x;
}

1 个答案:

答案 0 :(得分:6)

因为您在SFINAE上做错了,并且您也错误地使用了特征(没有::valueis_integer是布尔值)。特质的错误是微不足道的,而SFINAE的问题在于您为operator<<提供了非类型模板参数,但从未为其提供参数。您需要指定默认参数。

示例代码:

#include <cstdlib>
#include <iostream>
#include <type_traits>
#include <limits>

class Stream
{
public:
    Stream() {};

    template<typename T, std::enable_if_t<std::numeric_limits<T>::is_integer>* = nullptr>
    Stream& operator<<(const T& val)
    {
        std::cout << "I am an integer type" << std::endl;
        return *this;
    };

    template<typename T, std::enable_if_t<!std::numeric_limits<T>::is_integer>* = nullptr>
    Stream& operator<<(const T& val)
    {
        std::cout << "I am not an integer type" << std::endl;
        return *this;
    };
};

int main()
{
    Stream s;
    int x = 4;
    s << x;
}