首页 > 解决方案 > 如何定义正数的概念?

问题描述

我正在尝试创建一个编译时求和函数,并且我希望它确保它的所有给定参数都是正数:

template<typename T>
concept Positive = requires(T t) {
    { /*what should be here?*/ } ;
};

template<Positive... T>
int sum(T... x) {
    return (x + ...);
}

但我无法弄清楚如何做到这一点......

标签: c++c++20

解决方案


您的问题的明显答案是std::is_unsigned

但是,应避免使用无符号整数类型。它们与有符号类型的交互很奇怪。

因此,如果您使用有符号整数(如您所愿),概念将无济于事,因为概念是编译时检查,而整数的值在运行时是已知的。为此,您使用单元测试和断言。C++ 合约应该是实现此目的的工具,但不幸的是它已被推迟。

如果此函数是 constexpr 并在编译时评估,是否有办法在编译时检查正输入?

是的。您可以抛出,如果函数在常量表达式中进行评估,则会导致编译错误:

#include <stdexcept>

template <class... Args>
constexpr auto sum(Args... args)
{
    if ((... || (args < 0)))
        throw std::invalid_argument{"error negative number in sum"};
    return (... + args);
}

auto test()
{
    constexpr int r = sum(1, 2, -1); // <-- error here

    return r;
}

在函数auto test()中:在'constexpr'扩展sum<int, int, int>(1, 2, -1)错误:表达式''不是常量表达式

7 |         throw std::invalid_argument{"error negative number in sum"};
  |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

推荐阅读