模板元编程:乘以一堆模板参数
template Metaprogramming: multiplying a bunch of template arguments
我需要在编译时计算传递给模板化结构的一堆数字的乘积。我成功地做了一个丑陋的解决方案:
template<std::size_t n1, std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = n1 * mul_all<args...>;
};
template<>
struct mul_all<0>
{
static constexpr std::size_t value = 1;
};
问题是每次我必须像这样将 0 提供给模板参数到我的结构
int main()
{
std::cout << mul_all<1,2,5,4,5,7,0>::value << " "
<< mul_all<4,2,0>::value;
return 0;
}
是否有任何解决方法来读取最后一个零?
注意:我是 TMP 的初学者。
您需要将专业化替换为:
template<std::size_t n1, std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = n1 * mul_all<args...>::value;
};
template<std::size_t n>
struct mul_all<n>
{
static constexpr std::size_t value = n;
};
一种方法是专用于空可变参数。为此,您需要主模板仅为可变参数:
// main template never used
template<std::size_t ...args> struct mul_all
{
};
// specialization for at least one arg
template<std::size_t n1, std::size_t ...args>
struct mul_all<n1, args...>
{
static constexpr std::size_t value = n1 * mul_all<args...>::value;
};
// specialization for empty args
template<>
struct mul_all<>
{
static constexpr std::size_t value = 1;
};
现在你可以做:
mul_all<1, 2, 3>::value;
在C++17中,折叠表达式可以直接做
template<std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = (args * ...);
};
之前,您必须进行偏特化:
template<std::size_t n1, std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = n1 * mul_all<args...>::value;
};
template<std::size_t n>
struct mul_all<n>
{
static constexpr std::size_t value = n;
};
C++17 方法使这一切变得美好而简单:
template <std::size_t... A>
constexpr std::size_t mul = (A * ... * std::size_t(1u));
int main() {
constexpr std::size_t val = mul<1, 2, 3, 4>;
}
对于现有的 C++ 版本,您需要部分特化大小写 mul<v>
:
template <std::size_t... V> struct mul;
template <std::size_t V> struct mul {
statuc constexpr std::size_t value = V;
};
template <std::size_t V, std::size_t... T> struct mul {
statuc constexpr std::size_t value = V * mul<T...>::value;
};
template <std::size_t... V>
using mul_v = mul<V...>::value;
int main() {
constexpr std::size_t v = mul_v<1, 2, 3, 4>;
}
我需要在编译时计算传递给模板化结构的一堆数字的乘积。我成功地做了一个丑陋的解决方案:
template<std::size_t n1, std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = n1 * mul_all<args...>;
};
template<>
struct mul_all<0>
{
static constexpr std::size_t value = 1;
};
问题是每次我必须像这样将 0 提供给模板参数到我的结构
int main()
{
std::cout << mul_all<1,2,5,4,5,7,0>::value << " "
<< mul_all<4,2,0>::value;
return 0;
}
是否有任何解决方法来读取最后一个零?
注意:我是 TMP 的初学者。
您需要将专业化替换为:
template<std::size_t n1, std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = n1 * mul_all<args...>::value;
};
template<std::size_t n>
struct mul_all<n>
{
static constexpr std::size_t value = n;
};
一种方法是专用于空可变参数。为此,您需要主模板仅为可变参数:
// main template never used
template<std::size_t ...args> struct mul_all
{
};
// specialization for at least one arg
template<std::size_t n1, std::size_t ...args>
struct mul_all<n1, args...>
{
static constexpr std::size_t value = n1 * mul_all<args...>::value;
};
// specialization for empty args
template<>
struct mul_all<>
{
static constexpr std::size_t value = 1;
};
现在你可以做:
mul_all<1, 2, 3>::value;
在C++17中,折叠表达式可以直接做
template<std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = (args * ...);
};
之前,您必须进行偏特化:
template<std::size_t n1, std::size_t ...args>
struct mul_all
{
static constexpr std::size_t value = n1 * mul_all<args...>::value;
};
template<std::size_t n>
struct mul_all<n>
{
static constexpr std::size_t value = n;
};
C++17 方法使这一切变得美好而简单:
template <std::size_t... A>
constexpr std::size_t mul = (A * ... * std::size_t(1u));
int main() {
constexpr std::size_t val = mul<1, 2, 3, 4>;
}
对于现有的 C++ 版本,您需要部分特化大小写 mul<v>
:
template <std::size_t... V> struct mul;
template <std::size_t V> struct mul {
statuc constexpr std::size_t value = V;
};
template <std::size_t V, std::size_t... T> struct mul {
statuc constexpr std::size_t value = V * mul<T...>::value;
};
template <std::size_t... V>
using mul_v = mul<V...>::value;
int main() {
constexpr std::size_t v = mul_v<1, 2, 3, 4>;
}