C++概念看到我的类型的函数,但看不到 std::vector 的函数

C++ concepts see a function for my type, but don't see it for std::vector

本文关键字:函数 看不到 std vector 我的 类型 C++      更新时间:2023-10-16

我正在尝试在C++中实现像Haskell Prelude这样的东西,像Functor,Monoid等类型类。所以我决定使用C++概念进行类型检查,但是我在尝试实现半组概念时遇到了问题。

当我尝试声明一个概念时,就会出现问题,该概念使用某些函数,该函数在代码后面为所需的类型声明和重载,但它仅与某些类型(如 std::vector)相关,但对于我自己的类型效果很好。

完整代码:

template<class T>
struct S {
// ...
};
template<class T>
concept Addable = requires(T a, T b) {
{ add(a, b) } -> T;
};
template<class T>
S<T> add(const S<T> & a, const S<T> & b) {
// ...
return {};
}
template<class T>
std::vector<T> add(const std::vector<T> & a, const std::vector<T> & b) {
// ...
return {};
}
int main() {
std::cout << Addable<S<int>> << 'n';
std::cout << Addable<std::vector<int>> << 'n';
}

我希望输出1 1,但实际输出是1 0。 因此,无论声明的 add(std::vector) 重载如何,它都不会将 std::vector 识别为 Addable,但它确实将 S 类型识别为 Addable。

UPD:如果我将add函数移到Addable概念之前,问题就会消失。但是看起来非常不方便和不清楚的是,在包含这些概念之前,我必须实现我为std::vector等类型包含的所有概念。

UPD2:我使用 GCC 9.1.0。

我认为这是这个实验性 Clang 概念实现中的一个缺陷。[温度概念]/8 说:

概念不会被实例化([temp.spec])。

另请参阅:在哪些访问控制上下文中评估概念?

这意味着 [temp.res] 中描述的名称解析不适用于作为概念定义的表达式。如果必须实例化概念,则无法通过非限定名称查找找到函数add。这就是 Clang 生成错误的原因。

根据标准,当 id 表达式命名一个概念时,在出现 id 表达式 ([expr.prim.id]/4) 的位置计算规范化约束表达式。

不太正式的是,作为概念定义的表达式在命名概念的表达式的上下文中计算。所以Addable<vector<int>>应该是真的,因为在此表达式的上下文中,可以通过非限定名称查找找到add