Can I default initialize a parameter pack to the respective value initialization of each type ?
To elaborate a bit more, take the example of a simple function template
template<typename T>
void f(T arg = T())
{
// eg for T=int, arg is 0 (value initialization) when default initialized
}
Would it be possible to express its variadic counterpart, ie
template<typename... Args>
void F(Args... args /* how can I value initialize the parameter pack? */)
{
}
#include <iostream>
#include <utility>
#include <tuple>
#include <cstddef>
#include <type_traits>
template <typename... Args>
void F(Args... args)
{
// target function, arbitrary body
using expander = int[];
(void)expander{ 0, (void(std::cout << args << " "), 0)... };
std::cout << std::endl;
}
template <typename... Args, typename... Params, std::size_t... Is>
void F(std::index_sequence<Is...>, Params&&... params)
{
F<Args...>(std::forward<Params>(params)...
, std::decay_t<typename std::tuple_element<sizeof...(Params) + Is, std::tuple<Args...>>::type>{}...);
}
template <typename... Args, typename... Params>
auto F(Params&&... params)
-> std::enable_if_t<(sizeof...(Args) > sizeof...(Params))>
{
F<Args...>(std::make_index_sequence<sizeof...(Args) - sizeof...(Params)>{}
, std::forward<Params>(params)...);
}
Tests:
#include <string>
int main()
{
// F(int, char, float = float{}, double = double{})
F<int, char, float, double>(1, 'c');
// F(int = int{}, char = char{}, float = float{}, double = double{})
F<int, char, float, double>();
// F(const std::string&, const std::string& = std::string{})
F<const std::string&, const std::string&>("foo");
// F(int, int, int)
F(1, 2, 3);
}
Output:
1 'c' 0 0
0 '\0' 0 0
"foo" ""
1 2 3
DEMO
You can create two parameter packs, one representing the types corresponding to function parameters and one representing "defaulted parameters."
template< typename ... aux, typename ... arg >
void fn( arg ... a ) {
std::tuple< aux ... > more {}; // The tuple elements are value-initialized.
}
http://coliru.stacked-crooked.com/a/1baac4b877dce4eb
There is no way to explicitly mention the deduced template parameters for this function. Anything inside the angle braces of the call will go into aux, not arg.
Note, the initialization you get with {} is value-initialization, not default-initialization. Objects of fundamental type get zeroed, not left uninitialized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With