I want to write template function which can print container like std::vector
, std::list.
Below is my function, just overload <<
.
@miradham explained the issue very well.
but this a more generic solution using SFINAE to make the overload considered only for types on which the range-based for loop can be used, what ever their template arguments can be.
type coming form std::basic_string
were ignored to prevent ambiguity with the standard operator <<
to display strings
c-style array will not be displayed using this overload even though they could because they are decayed to pointers and displayed with the standard operator <<
#include
#include
#include
#include
#include
template typename From, typename T>
struct is_from : std::false_type {};
template typename From, typename ... Ts>
struct is_from > : std::true_type {};
template
using void_t = void;
template
struct is_input_iterator : std::false_type { };
template
struct is_input_iterator()),
decltype(*std::declval()),
decltype(std::declval() == std::declval())>>
: std::true_type { };
template()))>::value &&
is_input_iterator()))>::value &&
!is_from::value, int>::type = 0>
std::ostream& operator<<(std::ostream& out, const Container& c){
for(const auto& item:c){
out << item << " ";
}
return out;
}
int main(){
std::array arr{0, 1, 2, 3, 4, 5};
std::vector vec{5, 9, 1, 4, 6};
std::cout << vec << std::endl;
std::cout << arr << std::endl;
std::cout << std::string("test") << std::endl;
return 0;
}