Reputation: 1731
I have a function template defined as follows:
template <typename T>
Test &operator<<(const T &data)
{
std::cout << data << std::endl;
return *this;
}
As you can see, I print out to the console data
using std::cout
, which type is std::ostream
. However, T
may not be a type handled by std::ostream::operator<<
.
That's why I'd like to add a static_assert
to check whether T
is accepted by the insertion operator or not. Currently, I must do a check for every type that std::ostream::operator<<
accept:
template <typename T>
Test &operator<<(const T &data)
{
static_assert(std::is_arithmetic<T>::value ||
std::is_same<T, std::streambuf*>::value ||
...
std::is_same<T, std::string>::value, "data type must be compliant to std::ostream::operator<< accepted types");
std::cout << data << std::endl;
return *this;
}
Is there a type trait that automatically do that? What would you do?
Upvotes: 0
Views: 1392
Reputation: 171263
Why do you want a static_assert
? Is it acceptable to simply make the function not callable if the insertion isn't valid?
template <typename T>
auto operator<<(const T &data) -> decltype(std::cout << data, std::declval<Test&>())
{
std::cout << data << std::endl;
...
}
If you really want a trait see is_stream_insertable
Upvotes: 2