代码之家  ›  专栏  ›  技术社区  ›  Alexey104

为什么std::is_const_v在这里被评估为false?[副本]

  •  -1
  • Alexey104  · 技术社区  · 2 年前

    根据 cppreference :

    如果T是引用类型,则is_const<T>:值总是错误的。这个 检查潜在引用类型的常量的正确方法是 删除引用:is_const<typename移除引用<T>:类型>。

    这对参考文献来说是有意义的,因为没有 const 引用,可能只有一个对常量的引用。但指针不应该是这种情况,因为与引用不同,指针可以是 常量 。如果我想检查模板参数是否是 常量 指向的指针 常量 类型

    template<typename T>
    requires std::is_pointer_v<T> // Ok
             && std::is_const_v<std::remove_pointer_t<T>> // Ok
             // && std::is_const_v<T> // Fails (2)
    void foo(T t) { std::cout << *t << '\n'; }
    
    int main()
    {
        const int i{5};
        const int* const p{&i};
    
        static_assert(std::is_const_v<std::remove_pointer_t<decltype(p)>>); // Ok
        static_assert(std::is_const_v<decltype(p)>); // Ok (1)
    
        foo(p);
    }
    

    这里出了问题-约束 (2) 被评估为false。但与此同时 static_assert() (1) 被评估为true。为什么?它在某种程度上与模板参数推导有关吗?

    2 回复  |  直到 2 年前
        1
  •  2
  •   HolyBlackCat    2 年前

    它在某种程度上与模板参数推导有关吗?

    T t 永远不会推断 T const 。因为对调用者来说(顶级) 常量 完全不引人注意。

        2
  •  0
  •   user12002570    2 年前

    首先, T 被推断为 const int* 用于呼叫 foo(p)


    这里有问题——约束(2)被评估为false。但与此同时,static_assert()(1)被求值为true。为什么?

    因为 std::is_const_v 检查 顶层常量 但是 常量int* 有一个 低级常量 (不是 顶层常量 )。

    另一方面 decltype(p) const int* const 它有一个 顶层常量 是什么 标准::is_const_v 检查。