Default initialized (with value initialization) parameter pack

孤人 提交于 2019-12-10 22:09:03

问题


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? */)
{
}

回答1:


#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




回答2:


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.




回答3:


It`s explicitly forbidden by C++ standard, you cannot do such thing. N3376 8.3.6/3

A default argument shall be specified only in the parameter-declaration-clause of a function declaration or in a template-parameter (14.1); in the latter case, the initializer-clause shall be an assignment-expression. A default argument shall not be specified for a parameter pack.



来源:https://stackoverflow.com/questions/27686606/default-initialized-with-value-initialization-parameter-pack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!