为什么 `requires` 表达式不支持否定性要求?

编程语言 2026-07-11

例如,在简单概念中:

template <typename T>
concept Foo = requires (T t) {
    { t.bar().begin() };
    { t.bar().end() };

    { t.bar() } -> !std::convertible_to<std::string>; // For exposition only
};

在这里,我们想要断言关于 T(函数 T::bar() 的返回值)的某些内容满足一个要求。更重要的是,如何通过一个特定表达式来约束成立?就像一个没有二元运算符 operator+ 的类型:

template <typename T>
concept NonAddable = requires (T t) {
    ! { t + t }; // For exposition only
};

我知道我们可以这样重写:

template <typename T>
concept Foo = requires (T t) {
    { t.bar().begin() };
    { t.bar().end() };

    requires !requires {
        { t.bar() } -> std::convertible_to<std::string>;
    };
};

但这看起来有点过于复杂,老实说,一眼看去并不明显。此外,记住布尔代数:合取的否定是 析取!(E1 && E2 && ... && En)),也就是用符号 !E1 || !E2 || ... || !En 表示的析取。有人可能会错误地把不止一个否定表达式放进去,后来会惊讶地发现,这并不像直觉所示那样起作用。因此,对于多个负面要求,你必须写:

template <typename T>
concept Foo = requires (T t) {
    { t.bar().begin() };
    { t.bar().end() };

    requires !requires {
        { t.bar() } -> std::convertible_to<std::string>;
    };

    requires !requires {
        { t.qux() } -> std::convertible_to<int>;
    };

    requires !requires {
        ...;
    };
};

为什么不允许这样:

{ expr } -> !type-constraint

或者这个:

{ expr } !-> type-constraint

甚至这个:

! { expr } -> type-constraint

现实世界的例子,正如人们所问。设想一个类的概念,必须有一个函数,比如 description(),它必须返回一个包含不同类型元素的数组。这些类型的属性在此范围内并不重要(它们可能有某种将其转换成字符串的方式)。数组容器的类型并不重要,它只需要是可迭代的。另外,字符串(basic_string 及其所有表现形式)也是一种数组,但我们并不期望它出现在那里。它可以是数组的一个元素,而不是数组本身:

template <typename T>
concept Descriptive = requires (T t) {
    { t.description().begin() };
    { t.description().end() };

    requires !requires {
        { t.description() } -> std::convertible_to<std::string>;
    };

    requires !requires {
        { t.description() } -> std::convertible_to<std::wstring>;
    };

    requires !requires {
        ...;
    };
};

在我看来,这看起来既奇怪又违反直觉,但又如此容易添加。为什么不包含这样的东西?难道这不是显而易见的,它可能有用吗?

解决方案

如今的Concepts提案本身就是一项庞大且推进缓慢的工作。团队努力避免在没有强有力证据表明需要时增加额外的复杂性。你提出的这类负向约束显然对标准库并不有用,因此它们没有被纳入我们现在拥有的初始版本(也称为“Concepts Lite”)。

如果你能提供真实、有价值的用例证据,那么也许你可以参与标准化过程,提出一个经过深思熟虑、对你和他人有用的提案。不过,这并非轻而易举的事。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章