Reputation: 37
I am trying to write a stream class that handles numerical and non-numerical data separately. Can someone explain to me why this code does not compile?
#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;
}
Upvotes: 0
Views: 175
Reputation: 62603
Because you are doing SFINAE wrong, and you are also incorrectly using the trait (there is no ::value
, is_integer
is a boolean). The error with trait is trivial, the problem with SFINAE is that you gave a non-type template parameter to your operator<<
, but you never provide an argument for it. You need to specify a default argument.
Sample code:
#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;
}
Upvotes: 6