模板参数的乘法

Multiplication of Template Arguments

我有以下问题:

template< size_t... N_i >
class A
{
  // ...
  std::array< float, /* product of the unpacked elements of N_i */ > arr;
};

如您在上面所见,我尝试将名为 arrstd::array 声明为 class A 的成员。在这里,我希望 arr 具有 N_i 的解压缩元素的大小 乘积,例如,在 A<2,3,4>、[=25= 的情况下] 的大小应为 2*3*4=24.
有人知道如何实现吗?

在 C++14 中你可以这样做:

size_t v = 1;
size_t _[] = { (v = v*N_i)... };

作为一个最小的工作示例:

#include<cstddef>

template<std::size_t... I>
constexpr auto f() {
    std::size_t v = 1;
    std::size_t _[] = { (v = v*I)... };
    (void)_;  // silent a warning and nothing more
    return v;
}

int main() {
    static_assert(f<2,3,4>() == 24,"!");
}

你的class可以这样定义:

template< size_t... N_i >
class A {
    // ...
    std::array< float, f<N_i...>()> arr;
};

在 C++17 中 fold-expressions 会简化它。

在 C++17 中:

std::array < float, (... * N_i)> arr;

在 C++14 中:

// outside the class
template<size_t... Ns>
constexpr size_t product(){
    size_t p = 1;
    for(auto n : { Ns... }) p *= n;
    return p;
}

// then
std::array< float, product<N_i...>()> arr;

在 C++11 中:

template<size_t... N_i>
struct product { 
    static const size_t value = 1; 
};

template<size_t N_1, size_t... N_i>
struct product<N_1, N_i...> {
    static const size_t value = N_1 * product<N_i...>::value;
};

std::array< float, product<N_i...>::value> arr;

或者,您可以使用递归 constexpr 函数。

您可以在数组声明中使用此函数:

template<typename ...Args>
constexpr int multiply(Args&&... args)
{
    return (args * ... );
}

它使用C++17折叠表达式,并且可以像

一样被包含
template< size_t... N_i >
class A
{
  // ...
  std::array< float, multiply(N_i ...) > arr;
};

这可以通过constexpr函数的递归定义来完成。

并且在 c++14 中使用 variable template 这可以使外观更清晰:

template <typename ...Ts> 
constexpr size_t product()
{
    return  1;
}
template <size_t I,size_t... Is> 
constexpr size_t product()
{
    return   I * product<Is...>();
}

template <size_t I, size_t... Is> 
constexpr size_t prod = product<I, Is...>();


template< size_t... N_i >
class A
{
    std::array< float, prod<N_i...> > arr;
};