C++概念看到我的类型的函数,但看不到 std::vector 的函数
C++ concepts see a function for my type, but don't see it for std::vector
我正在尝试在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
。
- handleMessage看不到我的类和函数
- 为什么 connect() 函数看不到插槽?
- 为什么即使链接器找到目标文件,我的程序也看不到函数定义?
- C++概念看到我的类型的函数,但看不到 std::vector 的函数
- unique_ptr看不到派生类的自定义构造函数
- 看不到我在 c++ 中传递给另一个函数的主函数中的值
- 为什么命名空间中的函数看不到全局定义的运算符<<?
- 单例:为什么不需要删除并且看不到析构函数调试消息
- 我需要创建一个函数在用户下打印"=",但由于变量是使用 main() 声明的,因此函数看不到参数
- 为什么内联函数会导致编译器看不到OpenGL函数
- 友元函数看不到私有成员变量
- 为什么在从 c++ 中的函数返回对象的情况下,我看不到正在调用的复制构造函数?
- 在类模板上覆盖方法,编译器看不到它,只能看到其他重载函数
- 为什么内联函数看不到作用域内部?
- 链接器看不到在基类(纯虚拟)中定义的模板函数
- 编译器看不到函数,可以看到所有其他以相同方式使用的函数
- 在某些情况下,Visual Studio 看不到函数声明
- 为什么抽象类的实现看不到重载纯虚函数
- 为什么gcc链接器看不到我的析构函数
- C++lambda,看不到函数和参数