2014-08-27 23 views
12

Açık bir kopya ctor sahip nesnelerin bir kapsayıcı sıralanırken, derleyici hataları alıyorum (g ++ 4.8.2 ve clang ++ 3.4, in -std = C++ 11 modu) Anlamadım. Ben clang ++ ve ++ gAçık kopya yapıcı ve std :: sort

error: no matching function for call to ‘A::A(std::remove_reference<A&>::type) 

ile

error: 
    no matching constructor for initialization of '_ValueType' (aka 'A') 

ile sorunu

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; 
} 

Bu başarısız göstermek için basit bir örnek oluşturduk. Kod kopya oluşturucu açık değilse derler ve iyi çalışır (ancak yalnızca benim nesnelere yapılan başvuruların parametre ve geri dönüş değeri olarak kullanılabileceğini zorlamak istiyorum). Kod ayrıca çağrıyı std::sort'a kaldırdıktan sonra derler (bu nedenle is_less(objects[1], objects[2]) bir sorun değildir). Bu yüzden benim sorum, std :: sort'in, bu kodun derlenmesini sağlayan karşılaştırma işlevini çağırırken ve nasıl düzeltileceğini sorduğunda.

Çok fazla araştırmadan sonra, benim sorunuma yakın olan tek soru, gcc'deki bir hatayı bağlayan In copy-initialization, is the call to the copy constructor explicit or implicit?. Ancak, clang aynı davranışı gösterir, bu yüzden neler olduğunu anlamak isterim.

+6

Sadece çılgın insanlar kopya kurucular 'explicit', böyle tipleri ifade geçersiz kılan nedir –

cevap

12

std::sort, öğe tipinin MoveConstructible olmasını gerektirir.

MoveConstructible gereksinimleri, T u = rv; ifadesinin geçerli olması gerektiğini belirtir. Ancak, bu ifade, kopya başlatma işlemini gerçekleştirir ve açık olmayan bir kopya veya taşıma kurucusu olmasını gerektirir. Bu durumda, kopya kurucusu açıktır ve bunun açıkça bildirilen bir hareket yapıcısı olmadığı anlamına geldiğini bildirmektedir. Üste | Bu nedenle, ifade geçersiz ve A sınıfı MoveConstructible değil.

+7

değil CopyConstructible değildir yapmak sadece kopya yapıcısı sadece ilk bir kopya kurucu sahip bir yan etkisi olarak o da açık, fakat olduğunu yer, taşıma kurucusu devre dışı bırakıldı. Bir hareket ettirici ve hareket atama operatörü ile, kopya kurucusu hala açık olsa bile çalışır. – hvd

İlgili konular