2016-12-22 14 views
9

Rozważmy następujący kod:Usunięto konstruktor - MSVC zgłasza błąd, Clang nie

class SILPassPipelinePlan final { 
public: 
    SILPassPipelinePlan() = default; 
    ~SILPassPipelinePlan() = default; 
    SILPassPipelinePlan(const SILPassPipelinePlan &) = default; 
    SILPassPipelinePlan(SILPassPipelinePlan &&) = delete; 

    SILPassPipelinePlan x() { 
    SILPassPipelinePlan P; 

    return P; 
    } 
}; 

int main() { 
    return 0; 
} 

MSVC zgłasza następujący błąd:

1>consoleapplication2.cpp(13): error C2280: 'SILPassPipelinePlan::SILPassPipelinePlan(SILPassPipelinePlan &&)': attempting to reference a deleted function

1>consoleapplication2.cpp(8): note: see declaration of 'SILPassPipelinePlan::SILPassPipelinePlan'

Clang i GCC nie.

Z punktu widzenia specyfikacji, który kompilator jest prawidłowy? Czy jest to błąd MSVC, czy błąd Clang?

MSVC pochodzi z najnowszej aktualizacji Visual Studio 2015 Update 3, Clang w wersji 3.9.0.

+0

Która flaga '-std' przechodzi do Clang i GCC? Usunięcie konstruktora ruchu uległo istotnym zmianom między C++ 11 i C++ 14. – Angew

+0

@Angew brak konkretnych flag. Wypróbuj tutaj: http://rextester.com/WJMW74714 –

+1

Na podstawie tego linku w rextester używasz '-std = C++ 14'. Powinieneś dodać te informacje do pytania. – Angew

Odpowiedz

7

C++ 11 wprowadzono ukryte ruchy w niektórych scenariuszach — yours included:

In the following copy-initialization contexts, a move operation might be used instead of a copy operation:

  • If the expression in a return statement ([stmt.return]) is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, or

  • […]

overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If the first overload resolution fails, […]

dzyń (. Realizacja tylko przyjmowanie, btw) albo błędnie "nie" obejmuje wybór usuniętych funkcji, lub stosuje [over.match.funcs]/8 zbyt leniwy. Zobacz błąd 31025.

+0

Dzięki. Coś jak 'return const_cast (P);' naprawia błąd - ale czy ma to efekty uboczne? –

+1

@HBellamy Z jednej strony uniemożliwia zastosowanie funkcji kopiowania. Czy istnieje jakiś konkretny powód, dla którego * usuwasz * ctor przenoszenia zamiast po prostu go nie dostarczać? Zdajesz sobie sprawę, że samo dostarczenie siebie nie oznacza, że ​​w twoim przypadku nikt nie zostanie domyślnie zadeklarowany? Zobacz [\ [class.copy.ctor \]/(8.1)] (http://eel.is/c++draft/class.copy.ctor#8.1). – Columbo

4

Wszystkie wersje GCC na Wandbox odrzucają ten kod. Czy przez przypadek testujesz to na Macu i używając jego Clang-masquerading-as-GCC?

Nie ma to nic wspólnego z P0135. Clang jest po prostu biorąc nadmiernie liberalnej odczyt „nie” w tym, co jest obecnie [class.copy.elision]/3, który mówi, że w tej sytuacji

overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If the first overload resolution fails or was not performed, [...], overload resolution is performed again, considering the object as an lvalue.

To przeciążenie rozdzielczość nie powiedzie; to się uda i wybiera konstruktor ruchu, który ma zostać usunięty. To powinien być koniec sprawy.

Zostało to zgłoszone jako bug 31025.

+0

@columbo jakiejkolwiek odpowiedzi? –

+0

@HBellamy Powiedz co? Poprawiłem odpowiedź odpowiednio. – Columbo

Powiązane problemy