首页 > 解决方案 > 类模板的 requires 子句是否必须在成员定义之外重复?

问题描述

当使用该requires子句的类模板的成员在类外部定义时,如果未指定gcc则不抱怨,反之则抱怨。requiresclang

考虑下面的代码片段:

#include <concepts>

template<typename Container>
    requires std::integral<typename Container::value_type>
class Foo {
public:
    void func();
};

template<typename Container>
void Foo<Container>::func()
{}

编译使用gcc不会抱怨。

虽然clang报告以下错误:

❯ clang++ -std=c++2a test.cpp
test.cpp:10:1: error: requires clause differs in template redeclaration
template<typename Container>
^
test.cpp:4:19: note: previous template declaration is here
    requires std::integral<typename Container::value_type>
                  ^
1 error generated.

如果我将定义更改如下:

template<typename Container>
    requires std::integral<typename Container::value_type>
void Foo<Container>::func()
{}

现在clang不抱怨了。

输出gcc --version

gcc (GCC) 10.2.0

输出clang --version

clang version 10.0.1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

这是要报告的错误吗?

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

解决方案


应该为 GCC 提交一个错误,因为它接受代码,即使类外部成员的声明没有等效的模板头。

[温度等级]

3当在类模板定义之外定义成员函数、成员类、成员枚举、静态数据成员或类模板的成员模板时 ,将成员定义定义为模板定义,其中 template-head相当于类模板([temp.over.link])。

[temp.over.link]

6两个模板头是等价的,如果它们的模板参数列表具有相同的长度,对应的模板参数是等价的,并且都用类型约束声明,如果任何一个模板参数用类型约束声明,则它们是等价的,并且如果任一模板头有一个 requires-clause,它们都具有 requires-clauses并且相应的约束表达式是等价的。

模板头的等价性要求两者都有一个等价的 requires 子句。省略它完全破坏了等价性。


推荐阅读