如何为模板参数包指定默认参数?

3

我有以下方法

template <std::size_t N, std::size_t... Indices>
void doSomething()
{
    ...
};

似乎无法为“Indices”提供默认值,例如:Indices
template <std::size_t N, std::size_t... Indices = std::make_index_sequence<N>>
void doSomething()
{
    ...
};

编译器报错,提示

error: expected primary-expression before '>' token
template <std::size_t N, std::size_t... Indices = std::make_index_sequence<N>>
                                                                             ^~
error: template parameter pack 'Indices' cannot have a default argument
template <std::size_t N, std::size_t... Indices = std::make_index_sequence<N>>
                                    ^~~

有什么解决方法吗?


2
包不允许有默认参数。通常的做法是创建一个 template <std::size_t N> void doSomething() 版本的 doSomething,并调用带有所需包的那个函数。 - NathanOliver
顺便提一句,std::make_index_sequence<N>不是std::size_t...。如果合法的话,你需要像这样使用std::size_t... Indices = [0, 1, 42] - Jarod42
2个回答

2

这是不可能的。然而,你可以使用index_sequence来包装参数包,并在函数体中展开它们。

#include <cstddef>
#include <utility>

template <std::size_t N, class Indices = std::make_index_sequence<N>>
void doSomething() {
  []<std::size_t... Is>(std::index_sequence<Is...>) {
    // expand parameter pack
  }(Indices{});
};

Demo


2
到目前为止已经有两个很好的回答(包括 NathanOliver 的评论)。我认为在这里,拥有一个作为包装器的一对重载是最简单的解决方案,但为了完整起见,让我们提供一个函数来实现您所需的功能:
通常最好尽可能多地将模板逻辑从参数列表中拿出来(将输入与逻辑分开):
template <std::size_t N, std::size_t... Indices>
void doSomething()
{
    using Ints
        = std::conditional_t<
            /* if */ (sizeof...(Indices) > 0),
                std::index_sequence<Indices...>,
            /* else */
                std::make_index_sequence<N>>;

    // ...
};

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接