I have a function with two parameter packs where I can control what ends up in each one of them.
#include <iostream>
using namespace std;
template< typename... Args0, typename... Args1>
void func( Args0&&... args0, Args1&&... args1 ) {
cout << "args0: ";
(cout << ... << args0);
cout << '\n';
cout << "args1: ";
(cout << ... << args1);
cout << '\n';
}
int main() {
func<int, int, int>( 1, 2, 3, 4, 5, 6 );
cout << '\n';
func<int, int>( 1, 2, 3, 4, 5, 6 );
}
//Output from both GCC and Visual Studio.
// args0: 123
// args1: 456
//
// args0: 12
// args1: 3456
Demo: https://godbolt.org/z/n6T3h9dr5
This works both in GCC and Visual Studio C++.
I would have thought this was not valid code. Is this "undefined behaviour", or can I safely start utilizing this?
Edit: Added example of usage
template<typename... Args>
ostream & operator<<( ostream & out, const tuple<Args...> & tup ) {
auto func = [&]( const auto&... args_first, const auto&... arg_last ) {
out << "{ ";
((out << args_first << " , "), ...);
((out << arg_last), ...);
out << " }";
};
apply( func, take_firsts( tup ), take_last( tup ) );
return out;
}