显式复制构造函数和std :: sort [英] Explicit copy constructor and std::sort
问题描述
在对具有显式副本ctor的对象进行排序时,我得到了我不理解的编译器错误(来自g ++ 4.8.2和clang ++ 3.4,均处于-std = c ++ 11模式).我创建了一个简单的示例来演示该问题
When sorting a container of objects having an explicit copy ctor I get compiler errors (from g++ 4.8.2 and clang++ 3.4, both in -std=c++11 mode) that I don't understand. I've created a simple example to demonstrate the problem
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 ++中和
in clang++ and with
error: no matching function for call to ‘A::A(std::remove_reference<A&>::type)
在g ++中为
.如果复制构造函数不是显式的,则代码可以编译并正常工作(但我想强制执行仅将对对象的引用用作参数和返回值).删除对std::sort
的调用后,代码也会编译(因此is_less(objects[1], objects[2])
没问题).因此,我的问题是,在调用使编译此代码失败的比较函数时,std :: sort会做什么,以及如何解决该问题.
in g++. The code compiles and works fine if the copy constructor is not explicit (but I want to enforce that only references to my objects can be used as parameters and return values). The code also compiles after removing the call to std::sort
(so is_less(objects[1], objects[2])
is not a problem). Hence my question is what std::sort does when calling the comparing function that makes compiling this code fail and how to fix it.
After a lot of research, the only question that came close to my problem is In copy-initialization, is the call to the copy constructor explicit or implicit? which links to a bug in gcc. However, clang shows the same behavior, so I'd really like to understand what's going on.
推荐答案
std::sort
要求元素类型为MoveConstructible
.
对MoveConstructible
的要求指出,表达式T u = rv;
必须有效.但是,此表达式执行复制初始化,并要求有一个非显式的复制或移动构造函数.
The requirements for MoveConstructible
state that the expression T u = rv;
must be valid. However, this expression performs copy initialization and requires that there is a non-explicit copy or move constructor.
在这种情况下,副本构造函数是显式的,声明它意味着没有隐式声明的move构造函数.因此,该表达式无效,并且类A
不是MoveConstructible
.
In this case, the copy constructor is explicit, and declaring it means that there is no implicitly-declared move constructor. Therefore, the expression is invalid, and the class A
is not MoveConstructible
.
这篇关于显式复制构造函数和std :: sort的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!