【问题标题】:Why I can't use concept keyword before template argument?为什么我不能在模板参数之前使用概念关键字?
【发布时间】:2021-12-26 18:18:29
【问题描述】:

有一些讨论在 C++ 20 中很难看到模板参数的“种类”(我不想说类型,因为当涉及到模板时这是一个令人困惑的术语)。您可以阅读示例here

我有点希望 C++ 允许垃圾邮件的方式来指定模板参数是概念(通过在其前面加上 concept 关键字,但这不起作用。

这是有原因的,还是没有人认为它会有用,因为它有点长?

Example:

struct S{
  int x;
};

template <struct S s, /*concept*/std::integral> 
struct S2{
    auto f(){
        return s.x;
    }
};

int main() {
    constexpr S s{47};
    S2<s, short> s2;
    return s2.f(); 
}

在这里我可以通过在 S 之前添加结构来提高可读性(恕我直言),但 std::integral 之前的概念无法编译。

【问题讨论】:

  • 没有概念的前向声明。见why-is-there-no-forward-declaration-in-concepts-c
  • 如果我不得不猜测的话,我会说这是因为你特别应该这样想。您应该将S2 视为“采用Sstd::integral”。其中一个是结构,一个是概念,这一事实是还原论的。满足这两个约束,你就很好了。
  • 这是一个有趣的怪癖。 struct S s 这里等同于class S s。现在,删除参数 name class S... aa,现在它是一个类型模板参数。一个标记将非类型参数和类型参数分开。我个人认为这种上下文敏感性很糟糕,因为我仍然希望有一天能将概念视为模板参数,我很高兴我们没有能力将概念关键字放在你可以展示的地方'不能放。

标签: c++ c++20 c++-concepts


【解决方案1】:

请记住,struct S 只是一种与 C 向后兼容的可供性。回想一下,在 C 中,您必须为使用 struct 名称添加前缀(除非您使用 typedef 它,这这就是为什么您在 C 代码中经常看到这种情况的原因)。 C++ 没有这样的规则,但为了允许 C++ 编译器将 C 的子集编译为 C++,开发人员允许在类型名前加上 struct(或 class)。

C++20 的作者并没有刻意为template&lt;struct S s&gt; 赋予消除歧义的含义。这就是 C++ 中类型名称规则的工作原理。

同样,concept concept_name 从未被认为是命名概念的可能性。预计特定类型名称和使用约束类型参数的概念之间的任何歧义都应该由您使用的特定名称而不是语法来分类。你应该知道std::integral 是一个概念,而不是一个特定的类型名。

对于一些概念名称,这很清楚;很难对迭代器了解很多,也不知道random_access_iterator 是一个概念而不是特定类型。对于其他名称,就不太清楚了。

【讨论】:

  • Wrt struct: C legacy 是个好点,但它也适用于 enum...godbolt.org/z/67P5Mc9h4
  • @NoSenseEtAl - 但是枚举也与 C 共享...其中枚举的正确名称是 enum E
  • @StoryTeller-UnslanderMonica 好点,TILed :D 你可以使用枚举,但不能在模板参数中使用枚举类(我的意思是作为源中的文字字符串,你显然可以使用枚举类作为模板参数)
猜你喜欢
  • 2021-12-24
  • 2021-10-05
  • 1970-01-01
  • 2021-12-26
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多