The default parameter is initialized (with value initialization)

Can I initialize a parameter package by default to properly initialize the values โ€‹โ€‹of each type?

For more details, take an 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 } 

Is it possible to express its variational analogue, i.e.

 template<typename... Args> void F(Args... args /* how can I value initialize the parameter pack? */) { } 
+3
source share
3 answers
 #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

+3
source

You can create two packages of parameters, one of which represents the types corresponding to the parameters of the function, and one that represents the "default 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

It is not possible to explicitly specify the outputted template parameters for this function. Everything inside the call angle brackets will be aux , not arg .

Note that the initialization obtained with {} is the initialization of the value, not the default initialization. Objects of a fundamental type are nullified, and do not remain uninitialized.

+3
source

This is explicitly prohibited by the C ++ standard; you cannot do this. N3376 8.3.6 / 3

The default argument should only be specified in Parameter-declaration-sentence of the function declaration or template-parameter (14.1); in the latter case, the initializer clause must be an assignment expression. The default argument should not be for the parameter package.

+2
source

Source: https://habr.com/ru/post/1235786/


All Articles