Reputation: 317
I have the following structs:
struct A
{
}
struct B
{
tuple<string,string> children{{"test1","test2"}};
}
I would like to create a template function that will overload the << operator on every class having a member variable called children. If possible- only on tuples named children.
When a class with a children tuple like B is met it should iterate the tuple members and call << on each of them.
Something like:
template<typename RECEIVERTYPE,typename SENDERTYPE>
typename std::enable_if<std::have_children_member<RECEIVER_TYPE>::value, void>::type
RECEIVERTYPE& operator<< (RECEIVERTYPE& streamReceiver, const SENDERTYPE& streamSender)
{
for_each(streamSender.children, [&](const auto& child)
{
streamReceiver << child;
});
return streamReceiver;
}
I have tried alot of examples- but I cant really get anything working in visual studio 2015.
Upvotes: 0
Views: 886
Reputation: 171303
I would just do this to only match types with a tuple member called children
:
template<typename S, typename T,
std::size_t = std::tuple_size<decltype(T::children)>::value>
S& operator<<(S& s, const T& t)
{ ... }
And might implement the body like this:
template<typename S, typename T, std::size_t... I>
void
print_tuple_like(S& s, const T& t, std::index_sequence<I...>)
{
void* unused[] = { &(s << std::get<I>(t))... };
}
template<typename S, typename T,
std::size_t N = std::tuple_size<decltype(T::children)>::value>
S& operator<<(S& s, const T& t)
{
print_tuple_like(s, t.children, std::make_index_sequence<N>{});
return s;
}
Or like:
template<std::size_t N, typename S, typename T>
void
print_tuple_like(S& s, const T& t, std::false_type)
{ }
template<std::size_t N, typename S, typename T>
void
print_tuple_like(S& s, const T& t, std::true_type)
{
s << std::get<N>(t);
print_tuple_like<N+1>(s, t, std::integral_constant<bool, (N+1 < std::tuple_size<T>::value)>{});
}
template<typename S, typename T,
std::size_t N = std::tuple_size<decltype(T::children)>::value>
S& operator<<(S& s, const T& t)
{
print_tuple_like<0>(s, t.children, std::integral_constant<bool, (N != 0)>{});
return s;
}
Upvotes: 4