我可以默认将参数包初始化为每种类型的相应值初始化吗?
再详细说明一下,以一个简单的函数模板为例
template<typename T>
void f(T arg = T())
{
// eg for T=int, arg is 0 (value initialization) when default initialized
}
是否有可能表达其可变对应物,即
template<typename... Args>
void F(Args... args /* how can I value initialize the parameter pack? */)
{
}
答案 0 :(得分:3)
您可以创建两个参数包,一个表示与功能参数对应的类型,另一个表示“默认参数”。
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
无法明确提及此功能的推导模板参数。通话的角括号内的任何内容都将进入aux
,而非arg
。
注意,使用{}
进行的初始化是值初始化,而不是默认初始化。基本类型的对象变为零,而不是未初始化。
答案 1 :(得分:3)
#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)...);
}
试验:
#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);
}
输出:
1 'c' 0 0
0 '\0' 0 0
"foo" ""
1 2 3
答案 2 :(得分:2)
它被C ++标准明确禁止,你不能做这样的事情。 N3376 8.3.6 / 3
默认参数只能在。中指定 函数声明的参数声明子句或在 template-parameter(14.1);在后一种情况下,初始化子句 应该是一个赋值表达式。 默认参数不得为 为参数包指定。