2015-12-07 9 views
11

mi sarei aspettato questa affermazione statica al fuoco:Perché is_copy_constructible tornare vero per unique_ptr in MSVC12

#include <type_traits> 
#include <memory> 

int main() { 
    static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, "UPtr has copy constructor?"); 
} 

ma non è così.

compilato utilizzando MSVC12:

Microsoft (R) C/C++ compilatore di ottimizzazione Versione 18.00.31101 per x64

+1

Dispari. Su GCC 5 (Linux), l'asserzione si attiva. – hlt

+1

Non funziona con g ++: http://coliru.stacked-crooked.com/a/d0592d5e7824f2cd – NathanOliver

+0

Errore su [webcompiler] (http://webcompiler.cloudapp.net/) che, per quanto ne so, è relativamente aggiornato studio visivo. –

risposta

15

Il static_assert dovrebbe sparare, std::unique_ptr ha un costruttore di copia implicitamente cancellato, quindi questo è un bug Questo sembra correlato a questo bug report std::is_copy_constructible is broken:

(1) std :: rendimenti is_copy_constructible veri per i tipi con cancellati costruttori di copia.

(2) std :: is_copy_constructible restituisce true per i tipi che compongono i tipi non copiabili.

e la risposta è stata:

Grazie per aver segnalato il bug. Abbiamo risolto, e la correzione sarà disponibile nella prossima versione di Visual Studio dopo 2013.

Inoltre, vedere questo bug report: std::is_copy_constructible doesn't work correctly.

Nota che gli incendi asserzione su webcompiler che sta utilizzando una versione aggiornata di Visual Studio. L'ultimo aggiornamento era Dec 3, 2015. L'asserzione spara anche su clang (see it live) e gcc.

ho trovato un bug report: A strange behavior of std::is_copy_constructible che ha codice molto simile al tuo:

static_assert(std::is_copy_constructible<std::unique_ptr<int>>::value, ""); 

La risposta c'è:

Grazie per aver segnalato il bug. L'abbiamo già risolto e la correzione è disponibile in VS 2015 Preview.

Non chiaro, in quale versione di Visual Studio è stato risolto. Una risposta indica la versione di fine 2013, mentre la versione successiva di Anteprima 2015.

+0

Non conoscevo quel web-compilatore. Sarà uno strumento utile grazie. – sji

+0

"std :: unique_ptr non è né CopyConstructible né CopyAssignable" - Non confondiamo CopyConstructible e CopyAssignable (i concetti) con i controlli is_copy_constructible, ecc. Il primo è molto più forte del secondo. –

+0

@ T.C. Vedo come potrebbe essere confuso, risolto. –

0

Qui ci sono quattro modi per rendere classe non copiabile:

#include <stdio.h> 
#include <type_traits> 

class A { 
public: 
    A(const A&) = delete; 
    void operator=(const A&) = delete; 
}; 

class B { 
private: 
    B(const B&) = delete; 
    void operator=(const B&) = delete; 
}; 

class C { 
public: 
    C(const C&) = delete; 
    void operator=(const C&) = delete; 
    void operator=(C) = delete; 
}; 

class D { 
private: 
    D(const D&) = delete; 
    void operator=(const D&) = delete; 
    void operator=(D) = delete; 
}; 

int main() { 
    printf("%d %d\n", std::is_copy_constructible<A>::value, std::is_copy_assignable<A>::value); 
    printf("%d %d\n", std::is_copy_constructible<B>::value, std::is_copy_assignable<B>::value); 
    printf("%d %d\n", std::is_copy_constructible<C>::value, std::is_copy_assignable<C>::value); 
    printf("%d %d\n", std::is_copy_constructible<D>::value, std::is_copy_assignable<D>::value); 
} 

On MSVC2013 x64 (18.00.40629 for x64), esso stampa:

1 1 //A 
0 1 //B 
1 0 //C 
0 0 //D 

Su un compilatore corretto, tutti gli otto valori devono essere zeri .

Sfortunatamente, questo non fornisce un buon metodo per risolvere il problema in MSVC2013, anche per le proprie classi. Perché se dichiari che l'operatore di assegnazione accetta argomento per valore, non puoi dichiarare l'assegnazione di movimento nella stessa classe (qualsiasi assegnazione di movimento non verrà compilata a causa di un sovraccarico ambiguo).

P.S. L'idea chiave per l'assegnazione del compito è stata presa da this related answer.

Problemi correlati