Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用delete防止在C++;14_C++_C++14_Constexpr_Factorial - Fatal编程技术网

C++ 使用delete防止在C++;14

C++ 使用delete防止在C++;14,c++,c++14,constexpr,factorial,C++,C++14,Constexpr,Factorial,我可以使用模板和delete工具来防止使用字符或浮点变量调用factorial,如下所示。如何为带负参数的阶乘编写delete函数 template <typename T> constexpr T factorial(T n) { return (n == 1 || n == 0) ? 1 : (n * factorial(n - 1)); } constexpr float factorial(double) = delete; constexpr char facto

我可以使用模板和delete工具来防止使用字符或浮点变量调用factorial,如下所示。如何为带负参数的阶乘编写delete函数

template <typename T>
constexpr T factorial(T n)
{
    return (n == 1 || n == 0) ? 1 : (n * factorial(n - 1));
}

constexpr float factorial(double) = delete;
constexpr char factorial(char) = delete;

int main()
{
    constexpr auto fiveFactorial = factorial(5);
    constexpr auto point5fact = factorial(0.5); // Error. Call to deleted version
    constexpr auto letter5fact = factorial('5'); // DITTO
    constexpr auto minusFact = factorial(-1); // How to prevent this using delete?
}
模板
constexpr T阶乘(tn)
{
返回(n==1 | | n==0)?1:(n*阶乘(n-1));
}
constexpr float factorial(double)=删除;
constexpr char factorial(char)=delete;
int main()
{
constexpr auto-fiveFactorial=阶乘(5);
constexpr auto point5fact=factorial(0.5);//错误。调用已删除的版本
constexpr auto letter5fact=factorial('5');//同上
constexpr auto minusFact=factorial(-1);//如何使用delete防止这种情况?
}

不可能
=delete
是编译时的事情,而您的参数在编译时并不总是已知的

您可以改为使用
unsigned
参数并删除所有已删除的重载,代价是无法使用有符号数字调用函数,如
factorial(2)

template constexpr T阶乘(tn)
{
静态断言(std::is_unsigned_v&&!std::is_same_v,
“参数类型必须是整数、无符号,而不是'char'”;
返回(n==1 | | n==0)?1:(n*阶乘(T(n-1));
}

不可能
=delete
是编译时的事情,而您的参数在编译时并不总是已知的

您可以改为使用
unsigned
参数并删除所有已删除的重载,代价是无法使用有符号数字调用函数,如
factorial(2)

template constexpr T阶乘(tn)
{
静态断言(std::is_unsigned_v&&!std::is_same_v,
“参数类型必须是整数、无符号,而不是'char'”;
返回(n==1 | | n==0)?1:(n*阶乘(T(n-1));
}
如何为带负参数的阶乘编写delete函数

template <typename T>
constexpr T factorial(T n)
{
    return (n == 1 || n == 0) ? 1 : (n * factorial(n - 1));
}

constexpr float factorial(double) = delete;
constexpr char factorial(char) = delete;

int main()
{
    constexpr auto fiveFactorial = factorial(5);
    constexpr auto point5fact = factorial(0.5); // Error. Call to deleted version
    constexpr auto letter5fact = factorial('5'); // DITTO
    constexpr auto minusFact = factorial(-1); // How to prevent this using delete?
}
不能,因为参数的值是运行时属性,但只能删除基于类型的重载

但由于这是
constexpr
,还有另一种方法-您只需在常量表达式中对负输入使函数格式错误。例如,通过投掷。另外,由于您标记了此C++14,我将您的实现更改为循环:

template <typename T>
constexpr T factorial(T n)
{
    if (n < 0) throw std::runtime_error("bad user!");

    T product = 1;
    for (T i = 2; i <= n; ++i) {
        product *= i;
    }
    return product;
}

constexpr auto good = factorial(5); // fine
constexpr auto bad = factorial(-1); // compile error because factorial(-1)
                                    // is not a valid constant expression
模板
constexpr T阶乘(tn)
{
如果(n<0)抛出std::runtime_错误(“坏用户!”);
T积=1;
对于(ti=2;i
如何为带负参数的阶乘编写delete函数

template <typename T>
constexpr T factorial(T n)
{
    return (n == 1 || n == 0) ? 1 : (n * factorial(n - 1));
}

constexpr float factorial(double) = delete;
constexpr char factorial(char) = delete;

int main()
{
    constexpr auto fiveFactorial = factorial(5);
    constexpr auto point5fact = factorial(0.5); // Error. Call to deleted version
    constexpr auto letter5fact = factorial('5'); // DITTO
    constexpr auto minusFact = factorial(-1); // How to prevent this using delete?
}
不能,因为参数的值是运行时属性,但只能删除基于类型的重载

但由于这是
constexpr
,还有另一种方法-您只需在常量表达式中为负输入使函数格式错误。例如,通过抛出。此外,由于您标记了此C++14,我将您的实现更改为循环:

template <typename T>
constexpr T factorial(T n)
{
    if (n < 0) throw std::runtime_error("bad user!");

    T product = 1;
    for (T i = 2; i <= n; ++i) {
        product *= i;
    }
    return product;
}

constexpr auto good = factorial(5); // fine
constexpr auto bad = factorial(-1); // compile error because factorial(-1)
                                    // is not a valid constant expression
模板
constexpr T阶乘(tn)
{
如果(n<0)抛出std::runtime_错误(“坏用户!”);
T积=1;

对于(ti=2;i您不能,因为该值是在运行时计算的。类型也可以,因为它们在编译时是已知的,但是您不能得到只有在运行时才知道的编译器错误。我能看到的唯一解决方案是确保
T
是无符号类型。如果您只想允许无符号整数类型,是指仅声明泛型函数而不实现它(或者甚至可能将其标记为已删除?)。然后使用定义(实现)专门化无符号整数类型的函数。您不能这样做,因为该值是在运行时计算的。类型也可以,因为它们在编译时是已知的,但您无法获取仅在运行时已知的内容的编译器错误。我看到的唯一解决方案是确保
t
是无符号类型。作为另一种可能的解决方案,如果您只想允许unsigned整数类型,就是只声明泛型函数而不实现它(或者甚至可能将它标记为已删除?)。然后用定义(实现)专门化无符号整数类型的函数。OP的
factorial(5)
当然不再适用于此。如果OP对此没有问题,可以,但我认为它可以使用拼写。但现在需要调整实现:递归调用必须是
阶乘(n-1u)
,否则调用
阶乘(5us)
(具有无符号短值5的调用)将失败,因为
5us-1
的类型是
int
,它不是无符号的。@SebastianRedl Done.:/OP的
阶乘(5)
当然不再适用于此。如果OP对此没有问题,可以,但我认为它可以使用拼写。但现在需要调整实现:递归调用必须是
阶乘(n-1u)
,否则调用
阶乘(5us)
(具有无符号短值5的调用)将失败,因为
5us-1
的类型为
int
,它不是无符号的。@SebastianRedl Done.:/