[英]Is clang right to complain about an out of line definition of a templated constructor using a concept?
Here is a struct with a templated constructor that is defined out of line:这是一个带有模板化构造函数的结构,该构造函数被定义为异常:
template <typename T>
struct Foo {
template <typename F>
Foo(F f);
};
template <typename T>
template <typename F>
Foo<T>::Foo(F f) {}
Clang is happy with this under -std=c++20
. Clang对此感到满意
-std=c++20
。 If I add a requires
clause to the templated constructor, it is still happy.如果我向模板化构造函数添加一个
requires
子句,它仍然很高兴。 But if the requires
clause mentions the struct, it is not happy :但是如果
requires
子句提到结构,它就不高兴了:
#include <concepts>
template <typename T>
struct Foo {
template <typename F>
requires (!std::same_as<Foo<T>, int>)
Foo(F f);
};
template <typename T>
template <typename F>
requires (!std::same_as<Foo<T>, int>)
Foo<T>::Foo(F f) {}
<source>:13:9: error: out-of-line definition of 'Foo<T>' does not match any declaration in 'Foo<T>'
Foo<T>::Foo(F f) {}
^~~
GCC does accept this . GCC确实接受了这个。
Is clang right to reject it? clang拒绝就对了吗? And if so, what part of the standard says so?
如果是这样,标准的哪一部分是这样说的?
If you're interested why I have a requires
clause that references the type being constructed, it's to disambiguate the constructor from the move constructor so that the next requires
clause in a larger requires
expression won't be evaluated when F
is the same as Foo
.如果您对为什么我有一个引用正在构造的类型的
requires
子句感兴趣,这是为了消除构造函数与移动构造函数的歧义,以便当F
与Foo
相同时,不会评估更大的requires
表达式中的下一个requires
子句. Otherwise it recursively depends upon itself.否则它递归地依赖于它自己。 The real code is more complicated, and accepts a forwarding reference to
F
.实际代码更复杂,并接受对
F
的转发引用。
I think this could be related to the compiler not being able to deduce what T is.我认为这可能与编译器无法推断出 T 是什么有关。 When using a requires clause inside a struct, the compiler needs to be able to instantiate the class template in order to check the requirements specified in the requires clause.
在结构中使用 requires 子句时,编译器需要能够实例化 class 模板,以便检查 requires 子句中指定的要求。 This means that all template parameters used within the requires clause must be in scope and the compiler must be able to deduce their types.
这意味着 requires 子句中使用的所有模板参数必须在 scope 中,并且编译器必须能够推断出它们的类型。 If the class template is not fully defined yet, the compiler will not be able to instantiate it, and the code will not be able to compile.
如果class模板还没有完全定义,编译器将无法实例化它,代码将无法编译。 Just to be clear, I do not know with certainty, as I have barely used this feature.
需要明确的是,我不确定,因为我几乎没有使用过这个功能。
As I sort of expected, this seems to be a known clang bug: https://github.com/llvm/llvm-project/issues/49620正如我所料,这似乎是一个已知的 clang 错误: https://github.com/llvm/llvm-project/issues/49620
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.