c++ 为什么std::is_const_v在这里的计算结果为false?[重复]

hs1ihplo  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(224)
    • 此问题在此处已有答案**:

template argument deduction for const argument(2个答案)
4天前关闭。
根据cppreference
如果T是一个引用类型,那么is_const::value总是false。检查一个潜在引用类型常量性的正确方法是移除引用: 是常量〈类型名称删除引用::类型〉。 is_const<typename remove_reference::type>.
这对于引用是有意义的,因为没有const引用,可能只有一个常量引用,但指针不应该是这样,因为指针不像引用,可以是const,如果我想检查一个模板参数是否是const类型的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,这是为什么呢?是不是和模板参数推导有什么关系?

2admgd59

2admgd591#

是否与模板参数推导有关?
是的,T t永远不会将T推断为const,因为对于调用者来说,(顶级的)const是完全不明显的。

m3eecexj

m3eecexj2#

首先,T被推导为调用foo(p)const int*
这里有些问题- constraint(2)的值为false,但同时static_assert()(1)的值为true,这是为什么呢?
因为std::is_const_v检查顶级常量,但const int*低级常量(不是 * 顶级常量 *)。
另一方面,decltype(p)const int* const,它有一个顶级常量,这是std::is_const_v要检查的内容。

相关问题