数字类型的 C++ 概念和防止指针实例化

C++ concepts for numeric types and preventing instantiation on pointers

我正在尝试编写一个概念,如果模板参数只是数字类型(整数、浮点数、双精度等),则实例化一个函数,如果类型是指针类型或布尔值,则抛出错误类型。

#include <iostream>
#include <type_traits>
#include <boost/type_index.hpp>

template<typename T>
concept NumericType = requires(T param)
{
    {std::is_integral_v<T> || std::is_floating_point_v<T>};
    {!std::is_same_v<bool, T>};
    {std::is_arithmetic_v<decltype(param +1)>};
    !std::is_pointer_v<T>;
};

但是当我尝试将它与指向 int 或 float 或 double 的指针一起使用时,编译器会实例化该函数并将其加一到由于指针算法而起作用的指针。

template<NumericType T>
T add_one(const T val)
{
    return val + 1;
}

int main(){
    int two{2};
    int* pTwo = &two;
    float three{3.1415};


    std::cout << "add_one(two):  " << add_one(two) << "\n";
    std::cout << "add_one(&two): " << add_one(&two) << "\n";
    std::cout << "add_one(pTwo): " << add_one(pTwo) << "\n";
    std::cout << "add_one(&three): " << add_one(&three) << "\n";
    std::cout << "add_one(true):  " << add_one(true) << "\n";

    return 0;

}

我原以为编译器会在指针或布尔类型传递给 add_one 函数的情况下抛出错误,但令人惊讶的是它没有

我不明白概念 NumericType 的定义有什么问题,因为它在概念定义的正文中包含一个子句,提示编译器类型 T 不应该属于使用类型特征 std::pointer_v<T> `!std::is_same_v 的指针或布尔类型。这是编译器资源管理器上的 working example

requires子句只检查表达式的有效性,不计算值,需要使用嵌套requires:

template<typename T>
concept NumericType = requires(T param)
{
    requires std::is_integral_v<T> || std::is_floating_point_v<T>;
    requires !std::is_same_v<bool, T>;
    requires std::is_arithmetic_v<decltype(param +1)>;
    requires !std::is_pointer_v<T>;
};