简体   繁体   English

C++17 折叠表达式计算阶乘时出错

[英]Error in C++17 fold expression to calculate factorial

The following program gives errors in both g++ and clang...以下程序在 g++ 和 clang 中都给出了错误...

#include <iostream>
#include <utility>

using namespace std;

//Since C++17 one can use fold expression to calculate factorial:
template <class T, T N, class I = std::make_integer_sequence<T, N>>
struct factorial;

template <class T, T N, T... Is>
struct factorial<T,N,std::index_sequence<T, Is...>> {
   static constexpr T value = (static_cast<T>(1)* ... *(Is + 1));
};


int main(int argc, char** argv) {

    std::cout << factorial<int, 5>::value << std::endl;

    return 0;
}

Errors listed in gcc are as follows: gcc中列出的错误如下:

 error: type/value mismatch at argument 1 in template parameter list for 'template<long unsigned int ..._Idx> using index_sequence = std::integer_sequence<long unsigned int, _Idx ...>'
   24 | struct factorial<T,N,std::index_sequence<T, Is...>> {
      |                                               ^~~
note:   expected a constant of type 'long unsigned int', got 'T'
error: template argument 3 is invalid
   24 | struct factorial<T,N,std::index_sequence<T, Is...>> {
      |                                                  ^~
In function 'int main(int, char**)':
error: incomplete type 'factorial<int, 5>' used in nested name specifier
   31 |     std::cout << factorial<int, 5>::value << std::endl;
      |                                     ^~~~~

Clang errors are as follows: Clang错误如下:

error: template argument for non-type template parameter must be an expression
struct factorial<T,N,std::index_sequence<T, Is...>> {
                                         ^
D:\Programs\msys64\mingw64\include\c++\10.1.0\utility:344:22: note: template parameter is declared here
  template<size_t... _Idx>
                     ^
main.cpp:32:18: error: implicit instantiation of undefined template 'factorial<int, 5, std::integer_sequence<int, 0, 1, 2, 3, 4> >'
    std::cout << factorial<int, 5>::value << std::endl;
                 ^
main.cpp:22:8: note: template is declared here
struct factorial;
       ^

This example is shown in many sites.此示例在许多站点中都有显示。

Request somebody to help me correcting it.请求某人帮助我纠正它。

You used the wrong type for your result object.您为结果 object 使用了错误的类型。

std::index_sequence is a template that accepts only a pack of std::size_t . std::index_sequence是一个模板,它只接受一组std::size_t It doesn't accept a type parameter, because the type is fixed.它不接受类型参数,因为类型是固定的。 It is an alias template for std::integer_sequence<std::size_t, Ints...> .它是std::integer_sequence<std::size_t, Ints...>的别名模板。

So you trying to specify a type as its the first argument in std::index_sequence<T,...> is wrong.因此,您尝试将类型指定为std::index_sequence<T,...>中的第一个参数是错误的。

What you want is the more general type trait std::integer_sequence , making your specialization into this您想要的是更通用的类型特征std::integer_sequence ,使您的专业化成为

template <class T, T N, T... Is>
struct factorial<T,N,std::integer_sequence<T, Is...>> {
   static constexpr T value = (static_cast<T>(1)* ... *(Is + 1));
};

Live code example实时代码示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM