在C++20中,概念包含是指一个概念是另一个概念的超集。 例如,在以下示例中,
Fooable
包含 BetterFooable
:
template <typename T>
concept Fooable = requires(T& t) {
t.foo();
};
template <typename T>
concept BetterFooable = Fooable<T> && requires(T& t, int x) {
t.foo(x);
};
编译器能够看到
BetterFooable
被定义为Fooable
和其他东西,因此,任何满足BetterFooable
的类型也必然满足Fooable
。
这使我们能够部分专门化模板类:
template <Fooable T1>
struct MyStruct1 {};
template <BetterFooable T1>
struct MyStruct1<T1> {};
但是,具有模板参数包的类的特化似乎在 GCC 和 Clang 中都不可接受,但在 MSVC 中可以接受(godbolt 链接):
template <Fooable... Ts>
struct MyStruct2 {};
template <BetterFooable... Ts>
struct MyStruct2<Ts...> {};
GCC 产生的错误如下,Clang 产生的错误非常相似:
<source>:15:8: error: partial specialization 'struct MyStruct2<Ts ...>' does not specialize any template arguments and is not more constrained than the primary template; to define the primary template, remove the template argument list
15 | struct MyStruct2<Ts...> {};
| ^~~~~~~~~~~~~~~~
<source>:12:8: note: primary template here
12 | struct MyStruct2 {};
| ^~~~~~~~~
GCC 和 Clang 拒绝此代码是否正确,是否有其他方法可以在模板参数包中表达概念包含?
GCC 和 Clang 拒绝此代码是否正确
目前是的。
有没有其他方法可以在模板参数包中表达概念包含?
目前没有。
然而,P2963被C++26接受,其动机正是这里的例子。至少已经在 Clang 19 中实现了。