简体   繁体   English

默认初始化(带值初始化)参数包

[英]Default initialized (with value initialization) parameter pack

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

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 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 .调用的尖括号内的任何内容都将进入aux ,而不是arg

Note, the initialization you get with {} is value-initialization, not default-initialization.请注意,您使用{}获得的初始化是值初始化,而不是默认初始化。 Objects of fundamental type get zeroed, not left uninitialized.基本类型的对象被清零,而不是未初始化。

#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演示

It`s explicitly forbidden by C++ standard, you cannot do such thing. C++标准明确禁止,你不能做这样的事情。 N3376 8.3.6/3 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);默认参数只能在函数声明的参数声明子句或模板参数(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.不应为参数包指定默认参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM