Reputation: 6392
In this example on CppR:
template<typename Array, std::size_t... I>
decltype(auto) a2t_impl(const Array& a, std::index_sequence<I...>)
{
return std::make_tuple(a[I]...);
}
template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>>
decltype(auto) a2t(const std::array<T, N>& a)
{
return a2t_impl(a, Indices());
}
template<typename Func, typename Tup, std::size_t... index>
decltype(auto) invoke_helper(Func&& func, Tup&& tup, std::index_sequence<index...>)
{
return func(std::get<index>(std::forward<Tup>(tup))...);
}
template<typename Func, typename Tup>
decltype(auto) invoke(Func&& func, Tup&& tup)
{
constexpr auto Size = std::tuple_size<typename std::decay<Tup>::type>::value;
return invoke_helper(std::forward<Func>(func),
std::forward<Tup>(tup),
std::make_index_sequence<Size>{});
}
there are these lines, which confuse me a lot:
std::make_index_sequence<N>
std::make_index_sequence<Size>{}
Why are the curly braces added at the end at times (and omitting them causes a compile error) and why are they sometimes not?
Upvotes: 3
Views: 1806
Reputation: 315
The first instance (std::make_index_sequence<N>
) is used in a template argument list. It's only saying that the template type parameter Indices
defaults to the type std::make_index_sequence<N>
. No instances of anything are created there, the use is declarative.
The second instance (std::make_index_sequence<Size>{}
) is creating a default constructed instance of that type. The {}
are the new C++ syntax for initialization. When the braces are empty the object will be default constructed.
Upvotes: 3
Reputation: 50550
std::make_index_sequence
is ideally defined as:
template<std::size_t N>
using make_index_sequence = make_integer_sequence<std::size_t, N>;
std::make_integer_sequence
is ideally defined as:
template<class T, T N>
using make_integer_sequence = std::integer_sequence<T, /* a sequence 0, 1, 2, ..., N-1 */ >;
And std::integer_sequence
is a type from utility
header:
template< class T, T... Ints >
class integer_sequence;
Therefore, you can use it as any other type and invoke its default constructor, that is not strange at all.
See here for further details.
Upvotes: 3