- 此问题在此处已有答案**:
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,这是为什么呢?是不是和模板参数推导有什么关系?
2条答案
按热度按时间2admgd591#
是否与模板参数推导有关?
是的,
T t
永远不会将T
推断为const
,因为对于调用者来说,(顶级的)const
是完全不明显的。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
要检查的内容。