当对具有显式复制构造函数的对象容器进行排序时,我收到我不理解的编译器错误(来自 g++ 4.8.2 和 clang++ 3.4,均处于 -std=c++11 模式)。我创建了一个简单的示例来演示该问题
class A {
public:
explicit A(int i): m_i(i) {};
explicit A(const A& other): m_i(other.m_i) {};
int i() const {return m_i;};
private:
int m_i;
};
bool is_less(const A& a, const A& b) {
return a.i() < b.i();
}
int main(int, char*[]) {
std::vector<A> objects;
objects.push_back(A(3));
objects.push_back(A(5));
objects.push_back(A(-1));
std::cout << is_less(objects[1], objects[2]);
std::sort(objects.begin(), objects.end(), is_less);
for (auto& a: objects) {
std::cout << a.i() << " ";
}
std::cout << std::endl;
}
这失败了
error:
no matching constructor for initialization of '_ValueType' (aka 'A')
在 clang++ 中并与
error: no matching function for call to ‘A::A(std::remove_reference<A&>::type)
在 g++ 中。如果复制构造函数不显式,代码可以编译并正常工作(但我想强制只有对我的对象的引用才能用作参数和返回值)。删除对以下内容的调用后,该代码也会编译std::sort
(so is_less(objects[1], objects[2])
不是问题)。因此,我的问题是 std::sort 在调用导致编译此代码失败的比较函数时会做什么以及如何修复它。
经过大量研究后,唯一接近我的问题的问题是在复制初始化中,对复制构造函数的调用是显式的还是隐式的? https://stackoverflow.com/questions/21822438/in-copy-initialization-is-the-call-to-the-copy-constructor-explicit-or-implicit它链接到 gcc 中的一个错误。然而, clang 显示了相同的行为,所以我真的很想了解发生了什么。