模板元编程:将一堆模板参数相乘

时间:2016-12-31 13:30:59

标签: c++ templates template-meta-programming variadic

我需要在传递给模板化结构的编译时计算一堆数字的乘积。我成功地制作了一个丑陋的解决方案:

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;
};


问题是每次我必须向模板args提供0到这样的结构

int main()
{
    std::cout <<  mul_all<1,2,5,4,5,7,0>::value << " " 
              <<  mul_all<4,2,0>::value;
    return 0;
}


是否有任何解决方法可以读取最后一个零?

注意:我是TMP的初学者。

4 个答案:

答案 0 :(得分:6)

在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;
};

答案 1 :(得分:5)

您需要将您的专业化替换为:

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;
};

答案 2 :(得分:3)

一种方法是专注于空的varargs。为此,您需要主模板仅为可变参数:

// 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;

答案 3 :(得分:2)

C ++ 17方法简单明了:

CID

对于现有的C ++版本,您需要部分专门化案例Z

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>;
}