为什么我不能将两个不同的比较器传递给一个模板函数?
why can't i pass two different comparators to one template function?
我在这里绞尽脑汁了几个小时,但我仍然不明白为什么当我试图运行这段代码时我得到了一个错误。过了一段时间,我设法把它缩小到这个表达:
pastryPrice()
导致了这个问题—正如您所看到的,我试图为排序
的一个模板函数构建多个比较器 struct dialingAreaComp{
inline bool operator()(const Deliver *d1, const Deliver *d2)const {
return d1->getDialingArea() < d2->getDialingArea();
}
};
struct pastryPrice {
inline bool operator()(const Pastry *p1, const Pastry *p2)const {
return p1->getPrice() < p2->getPrice();
}
};
template<class T>
void sortCollection(T& collection)
{
if ( typeid (collection) == typeid(vector <Deliver*>))
{
sort(collection.begin(), collection.end(), dialingAreaComp());
printCollection(collection);
}
else if (typeid (collection) == typeid(vector <Pastry*>))
{
sort(collection.begin(), collection.end(), pastryPrice());
printCollection(collection);
}
else { cout << "WRONG!"; }
}
我得到了五个错误,都是一样的:
项目文件行抑制状态错误C2664 'bool Bakery::pastryPrice::operator ()(const Pastry *,const Pastry *) const':无法将参数1从'Deliver *'转换为'const Pastry *' Bakery c:program files (x86)microsoft visual studio 14.0vcincludexutility 809
还有一个
项目文件行抑制状态错误C2056非法表达式面包店c:program files (x86)microsoft visual studio 14.0vcincludexutility 809
当我去掉上面写的表达式时,代码工作得很好 -为什么我不能将两个不同的比较器传递给一个模板函数?
:
C2264是当试图向函数传递不兼容类型的形参时发生的编译错误。
但是交付函数工作,当我取下交付比较器时,糕点也编译了…那么什么是不相容类型呢?
你的问题是无论哪个分支被编译,两个分支都被编译。
我会用不同的方式处理这个问题。
template<class A, class B>
struct overload_t:A,B{
using A::operator();
using B::operator();
overload_t(A a, B b):A(std::move(a)), B(std::move(b)){}
};
template<class A, class B>
overload_t<A,B> overload( A a, B b ){
return {std::move(a),std::move(b)};
}
这允许我们重载两个函数对象或lambda。(可以添加完美转发,也可以添加变量…,但我保持它简单)。
现在我们简单地:
auto comp=overload(dialingAreaComp{}, pastryPrice{});
using std::begin; using std::end;
std::sort( begin(collection), end(collection), comp );
,编译器为我们选择正确的比较函数。当我在那里的时候也支持平面数组。
停止使用using namespace std;
上面的代码所做的是将两个函数对象类型合并为一个。using A::operator()
和using B::operator()
将()
移动到同一个类中,并告诉c++在使用通常的方法调用重载规则调用时在它们之间进行选择。其余的代码用于推断被重载的类型并移动构造它们。
sort
用编译时根据容器类型确定的类型的对象调用()
。重载解析(在调用点的sort
内)然后在编译时选择正确的体进行比较。
因此,技术可以扩展为支持2个以上的重载、函数指针和转发引用。在c++ 17中,可以做一些工作来让重载类型推断出它的父类型,从而不需要工厂函数。
您会得到一个错误,因为模板化的函数是在编译时求值的,并且其中一个函数调用永远不会匹配。用简单的函数重载代替模板:
void sortCollection(vector <Deliver*>& collection)
{
sort(collection.begin(), collection.end(), dialingAreaComp());
printCollection(collection);
}
void sortCollection(vector <Pastry*>& collection)
{
sort(collection.begin(), collection.end(), pastryPrice());
printCollection(collection);
}
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何仅为一个函数添加延迟
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 我需要将多个函数组合为一个函数
- 在C++中声明一个函数时,它需要有函数本身的参数吗
- 如何创建一个函数来计算并返回平均值、最大值和最小值
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 编写一个函数以使用 n 百分比的 CPU 使用率
- 将 N-arg 函数包装到另一个函数中
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- C++从另一个函数退出函数
- 编写一个函数来删除单链表中的节点(尾部除外),仅授予对该节点的访问权限
- 视觉我希望一个函数在另一个函数C++中进行计算
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 在另一个函数 (c++) 中调用变量
- 如何在另一个函数中使用返回值作为参数?
- 如何包装一个函数以适应另一个函数的所需类型
- 创建一个函数的 Python 绑定,返回指向带有 boost 的向量的指针