问题描述
GCC实现的P0634R3放弃了在已知上下文中指定类型typename
的需要。
它也适用于concept
吗?
因为以下代码无法编译:
template<typename T>
concept sample_concept =
std::default_initializable<T::value_type> &&
requires (T t) {
{ t.some_func(std::declval<T::some_type>()) }
-> std::same_as<T::iterator>;
};
但是当我在typename
和T::value_type
前面指定T::iterator
时,它将编译。
解决方法
在论文中,重点是我的:
因此,我们建议在许多仅允许输入类型名称的普通情况下使
typename
为可选。
该论文仅在您需要 具有类型的地方将typename
设为可选。在别名声明的右侧,必须是一种类型。在static_cast
中,必须是类型,等等。
但是这里:
template<typename T>
concept sample_concept = std::default_initializable<T::value_type>;
事实并非如此。尽管default_initializable
的参数是类型参数,但您也可以使用非类型模板参数或模板模板参数作为概念。因此,这不是仅允许类型名称的情况,因此typename
在这里仍然是强制性的。
您可能会问:好吧,在概念中具体,因为您不能重载一个概念或(当前)具有从属概念,所以您只需查看一下该概念,看看它是否带有类型。但是,这只是增加一点点复杂度就大大增加了,如果将来无论如何我们添加从属概念的话,它将变得更加复杂和缩小。