在我的 C++ 课上,我们正在学习使用函数对象等,但现在我们得到了一个代码片段,它可以在老师的编译器上运行,但不能在我们的编译器上运行(我们使用不同的操作系统)。
我们用几个编译器(MSVC,clang)测试了下面的代码片段,它们都拒绝了它,有点最小化:
#include <functional>
struct Fraction {
Fraction();
Fraction(int z, int n);
Fraction(Fraction&);
// various data members
};
struct FractionComparator {
int operator()(Fraction a, Fraction b) {
return 1;
}
};
int main() {
std::function<int(Fraction, Fraction)> comparator = FractionComparator();
}
我们在 macOS 上使用 clang:
No viable conversion from 'FractionComparator' to 'function<int (Fraction, Fraction)>'
我们已经发现添加移动构造函数可以解决问题,但我们不知道为什么存在这种差异以及为什么这段代码无法在我们的编译器上编译。
有什么想法吗?
最佳答案
为什么添加移动构造函数可以解决问题?
Fraction
试图从 rvalue 复制构造.
但是构造函数 Fraction(Fraction&);
采用非常量引用。不允许非常量引用绑定(bind)到临时对象。
正确的构造函数签名应该是:
Fraction(const Fraction&);
当您声明移动构造函数时,编译器将从右值移动构造 Fraction
。
为什么这段代码不能在我们的编译器上编译,而是在老师的编译器上编译?
此代码 compiles with VC++ .
看起来编译器不符合这里的标准。
我可以找到 this StackOverflow question有更多细节。它似乎是一个允许编译的编译器扩展。
如果通过 /Za
禁用编译器扩展,请标记它 will not compile不再。
关于c++ - 无法使用比较器初始化 std::function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50685620/