c++ - 是否必须在成员定义之外重复类模板 requires 子句?

标签 c++ templates language-lawyer c++20 c++-concepts

当使用 requires 的类模板的成员时子句在类之外定义,gcc如果 requires 不提示未指定,而 clang做。
考虑下面的代码片段:

#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
这是要报告的错误吗?

最佳答案

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

[temp.class]

3 When a member function, a member class, a member enumeration, a static data member or a member template of a class template is defined outside of the class template definition, the member definition is defined as a template definition in which the template-head is equivalent to that of the class template ([temp.over.link]).

[temp.over.link]

6 Two template-heads are equivalent if their template-parameter-lists have the same length, corresponding template-parameters are equivalent and are both declared with type-constraints that are equivalent if either template-parameter is declared with a type-constraint, and if either template-head has a requires-clause, they both have requires-clauses and the corresponding constraint-expressions are equivalent.


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

关于c++ - 是否必须在成员定义之外重复类模板 requires 子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63628752/

相关文章:

c++ - 当我们将特定类型传递给类模板时生成类

C++ 模板 std::tuple 到 void* 并返回

c - 是否应该使用 GLOB_MARK 将 glob 附加到符号链接(symbolic link)到目录的结果?

c++ - 为什么编译器不自动内联自由定义的函数?而是导致链接器错误

c++ - 访问二维数组 (T[N][M]) 作为大小为 N*M 的一维数组是否保证有效?

c++ - 如何在 C++ 中循环一个函数

c++ - 为什么使用对象实例而不是 class::static 函数?

c++ - 定义放置 C 字符串的位置

c++ - 动态内存 C++

java - 你如何在 Play Framework scala 模板中使用 DTO?