为什么 std::sort 不接受比较函数中声明的类
Why std::sort doesn't accept Compare classes declared within a function
我在工作,在一个函数中编写比较器(稍后,当我决定哪里最好时移动),并注意到了这种特殊性。 我想了一会儿,意识到我不明白为什么如果我使用内部比较器,代码将无法编译,但外部比较器很好。
有什么解释吗?
快速测试工具:
#include <iostream>
#include <vector>
#include <algorithm>
class CompareMe
{
public:
CompareMe(int in) : toCompare(in){}
int toCompare;
};
class Comparators
{
public:
bool operator()(CompareMe * first, CompareMe * second)
{
return first->toCompare < second->toCompare;
}
};
class ComparatorsOuter : public Comparators{};
int main()
{
class ComparatorsInner : public Comparators{};
std::vector<CompareMe *> compares;
compares.push_back(new CompareMe(0));
compares.push_back(new CompareMe(1234));
compares.push_back(new CompareMe(163));
compares.push_back(new CompareMe(6));
compares.push_back(new CompareMe(12));
//This works, and properly sorts the array
ComparatorsOuter comparator;
std::sort(compares.begin(), compares.end(), comparator);
//Uncomment out the sort below and it will not compile.
ComparatorsInner comparatorInner;
//std::sort(compares.begin(), compares.end(), comparatorInner);
std::vector<CompareMe *>::iterator it;
for(it = compares.begin(); it != compares.end(); ++it)
{
std::cout << (*it)->toCompare << std::endl;
}
}
错误:调用 '
sort(__gnu_cxx::__normal_iterator<CompareMe**, std::vector<CompareMe*, std::allocator<CompareMe*> > >, __gnu_cxx::__normal_iterator<CompareMe**, std::vector<CompareMe*, std::allocator<CompareMe*> > >, main()::ComparitorInner&)
' 没有匹配函数
在 C++03 中,模板参数不能有内部链接:
[C++03: 14.6.4.2/1]:
对于依赖于模板参数的函数调用,如果函数名称是非限定 id 而不是模板 id,则使用通常的查找规则(3.4.1、3.4.2)找到候选函数,但以下情况除外:
- 对于使用非限定名称查找 (3.4.1) 的查找部分,仅找到具有模板定义上下文中的外部链接的函数声明。
- 对于使用关联命名空间 (3.4.2) 的查找部分,仅找到在模板定义上下文或模板实例化上下文中找到的具有外部链接的函数声明。
[..]
这在 C++11 中进行了更改(问题 #561:"依赖名称查找中的内部链接函数"):
[C++11: C.2.6]:
14.6.4.2
更改:允许使用内部链接
调用函数 理由:过度约束,简化重载解决规则。
导致:
[C++11: 14.6.4.2/1]:
对于依赖于模板参数的函数调用,可以使用通常的查找规则(3.4.1、3.4.2、3.4.3)找到候选函数,但以下情况除外:
- 对于使用非限定名称查找 (3.4.1) 或限定名称查找 (3.4.3) 的查找部分,仅找到模板定义上下文中的函数声明。
- 对于使用关联命名空间 (3.4.2) 的查找部分,仅找到在模板定义上下文或模板实例化上下文中找到的函数声明。
[..]
(找出缺失的"与外部链接"资格。
由于您的main()::ComparitorInner&
具有内部链接,并且std::sort
的实例化需要此类型是模板参数(尽管是推导的),因此您的代码仅在 C++11 中有效。
您的代码在 C++11 中很好;在 C++03 中使用本地类型作为模板参数存在限制。
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 在c++中在类外声明函数有什么好处
- 使用 #define 声明函数
- 在静态库中声明函数,在使用该相同库的应用程序中定义它
- 如何强制编译器在 C/C++ 本身中声明函数?
- 如果您只需要在 .h 文件中声明函数.cpp是否需要在 .h 文件中声明函数?
- C++:<sys/sysctl.h> 无法声明函数CTL_HW和HW_NCPU
- 尝试声明函数的局部变量,但得到范围错误
- 如何在C++模板中声明函数
- 如何在另一个文件的类中声明函数
- 使用非类型模板参数正向声明函数模板
- 在此范围错误中未声明函数错误
- 当我们不能声明函数内联(GCC 编译器)时?
- 未在此作用域中声明函数,即使存在头文件也是如此
- 无法声明函数中的模板类型别名
- 单个CPP文件中多次声明函数声明可以吗?
- 编译一个支持VBA中声明函数的dll
- 使用从外部参数包中获取的参数类型声明函数
- 使用类成员正确地声明函数
- 在函数内重新声明函数