我以为我写了一个很好的概念,但是在提交之前我重新排序了它在我的文件中的位置,突然,程序结果是错误的(没有任何编译错误)!
这是一个与我所拥有的代码示例相匹配的代码示例,尝试在某些情况下进行特殊比较(请注意,此处名为“Compare”的函数在实际代码中具有更多功能,有几个针对不同类型的 SpecialCompare 函数,并且只有 1 个“比较”函数来使用它们,它的作用与仅使用 == 的“比较”函数不同):
#include <iostream>
#include <string>
#include <vector>
namespace
{
//Put CanDoSpecialCompare here, and the end result is different ("Same int, Different vector"))!
template<typename T>
bool SpecialCompare(const std::vector<T>& first, const std::vector<T>& second) {
return true; //Dummy implementation
}
//Put CanDoSpecialCompare here, and the end result is different ("Same int, Same vector"))!
template <typename T>
concept CanDoSpecialCompare = requires(T a, T b) {
SpecialCompare(a,b);
};
template<CanDoSpecialCompare T>
bool Compare(const T& a, const T& b) {
return SpecialCompare(a, b);
}
template<typename T>
bool Compare(const T& a, const T& b) {
return a == b;
}
}
int main() {
std::vector<int> v1{1,2}, v2{1,3};
int i1 = 1, i2 = 1;
if (Compare(i1,i2))
std::cout << "Same int, ";
else
std::cout << "Different int, ";
if (Compare(v1,v2))
std::cout << "Same vector" << std::endl;
else
std::cout << "Different vector" << std::endl;
}
我有点明白为什么会发生这种情况(在它测试的函数之前定义概念,所以它不会“看到”该函数?),但不完全明白(它是一个模板,仅在它需要的 SpecialCompare 函数模板之后使用,所以现在我使用这个概念,它应该看到SpecialCompare函数模板?)。
另外,如果我想将这个概念放在顶部,或者更好的是,我该如何编写这个概念,以便可以毫无问题地移动该概念?我想我也可以使用一个特质,但我的印象始终是概念更具可读性/更简短?
正如评论中已经提到的,该概念只能看到在其自身之前声明的名称,或由 ADL 引入的名称 - 并且名称查找失败仅算作对
false
的评估(毕竟,可能 是通过 ADL 引入的 SpecialCompare
对于一些T
)。
简单的解决方案是添加健全性检查,例如
template <typename T>
concept CanDoSpecialCompare = requires(T a, T b) {
SpecialCompare(a,b);
};
static_assert(CanDoSpecialCompare<std::vector<int>>);
就在概念之后。