我对C++ 11的功能比较陌生.我对自动功能以及它如何类型推断出仿函数有疑问.请考虑以下代码段:
bool test1(double a, double b) {
return (a<b);
}
bool test2(double a, double b) {
return (a>b);
}
struct Test1 {
bool operator()(double a, double b) {
return (a<b);
}
};
struct Test2 {
bool operator()(double a, double b){
return (a>b);
}
};
int main() {
const bool ascending = false;
auto comparator = ascending? test1:test2; // works fine
auto comparator2 = ascending? Test1():Test2(); // compiler error: imcompatible types
std::function<bool(double, double)> comparator3 = ascending? Test1():Test2(); // compiler error: imcompatible types;
}
Run Code Online (Sandbox Code Playgroud)
虽然auto(和std :: function)适用于函数,但它对函数对象失败(类型推导).为什么是这样?我在这里遗漏了一些基本的wrt类型演绎.
(我使用的是Visual Studio 2012)
And*_*owl 10
根据条件(?)运算符的C++ 11标准的第5.16/3段:
[...]如果第二个和第三个操作数具有不同的类型并且具有(可能是cv限定的)类类型,或者如果两者都是相同值类别的glvalues和除cv-qualification之外的相同类型,则尝试将每个操作数转换为另一个操作数的类型.[...] 如果两者都可以转换,或者一个可以转换,但转换含糊不清,则程序格式错误.[...]
在您的情况下,既Test1不能Test2也不能转换为其他类型.这就是编译器抱怨"不兼容类型"的原因.
Nptice,如果不是这种情况,那么类型comparator2和comparator3将在运行时根据值确定ascending.但是,C++是一种静态类型语言,这意味着必须在编译时确定所有对象的类型.
如果需要执行比较器的运行时选择并将结果保存在一个变量中,请考虑首先将两个对象分配给可以封装它们的相同类型的仿函数,然后执行选择:
std::function<bool(double, double)> c1 = Test1();
std::function<bool(double, double)> c2 = Test2();
auto c = (ascending) ? c1 : c2;
Run Code Online (Sandbox Code Playgroud)