可选的类型名称是否适用于概念?

问题描述

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>;
    };

但是当我在typenameT::value_type前面指定T::iterator时,它将编译。

解决方法

在论文中,重点是我的:

因此,我们建议在许多仅允许输入类型名称的普通情况下使typename为可选。

该论文仅在您需要 具有类型的地方将typename设为可选。在别名声明的右侧,必须是一种类型。在static_cast中,必须是类型,等等。

但是这里:

template<typename T>
concept sample_concept = std::default_initializable<T::value_type>;

事实并非如此。尽管default_initializable的参数是类型参数,但您也可以使用非类型模板参数或模板模板参数作为概念。因此,这不是仅允许类型名称的情况,因此typename在这里仍然是强制性的。

您可能会问:好吧,在概念中具体,因为您不能重载一个概念或(当前)具有从属概念,所以您只需查看一下该概念,看看它是否带有类型。但是,这只是增加一点点复杂度就大大增加了,如果将来无论如何我们添加从属概念的话,它将变得更加复杂和缩小。