我正在学习 C++ 概念中的嵌套需求。考虑以下代码片段:
#include <concepts>
#include <iostream>
// Nested requirement
template <typename... Ts>
concept VariadicAddable = requires(Ts... vs)
{
(... + vs); // + operator is provided
requires sizeof...(Ts) > 1; // Atleast two arguments are provided
};
template <VariadicAddable... Ts>
auto add_variadic(Ts... vs)
{
return (... + vs);
}
int main()
{
std::cout << add_variadic(1, 2) << std::endl; // Expecting no failure here
//std::cout << add_variadic(1) << std::endl; // Expecting failure here
}
编译这个时我遇到错误...(Godbolt,msvc vs17.10 带有 c++20 选项)
<source>(20): error C2672: 'add_variadic': no matching overloaded function found
<source>(13): note: could be 'auto add_variadic(Ts...)'
<source>(20): note: the associated constraints are not satisfied
<source>(12): note: the constraint was not satisfied
我还尝试了指定相同约束的变体,如下所示:
template <typename... Ts>
concept VariadicAddable = (sizeof...(Ts) > 1) && requires(Ts... vs)
{
(... + vs); // + operator is provided
};
在这种情况下也会出现类似的错误。知道我遗漏了什么吗?
问题是
concept
前面的模板类型参数应该约束单个类型,而不是多个类型参数之间的关系。你concept
本身没问题,但它不能按照你展示的方式使用。我尝试用 clang 进行编译,得到了稍微清晰一些的错误信息:
很明显,每个
int
概念都是VariadicAddable
单独检查的,而不是将整个包传递给概念。为了sizeof...(Ts)
大于 1(比如说是 2),模板参数之前的概念需要采用VariadicAddable<T>
某种类型的形式T
,而不仅仅是VariadicAddable
,但这显然不是您的意图。解决方法很简单:只需使用子句中的概念
requires
。