2016-12-22 21 views
9

考慮下面的代碼:刪除構造 - MSVC報告錯誤,鏘不

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報告以下錯誤:

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'

鏘和GCC沒有。

從規範的角度來看,哪個編譯器是正確的?這是一個MSVC錯誤還是一個叮鐺聲?

MSVC來自最新的Visual Studio 2015 Update 3,Clang的版本是3.9.0。

+0

你在傳遞給Clang和GCC的是哪個'-std'標誌?移動構造函數的刪除在C++ 11和C++ 14之間經歷了重要的變化。 – Angew

+0

@Angew沒有特定的標誌。試試這裏:http://rextester.com/WJMW74714 –

+1

基於rextester鏈接,你正在使用'-std = C++ 14'。您應該將此信息添加到問題中。 – Angew

回答

7

C++ 11引入在某些情況下— 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, […]

鏘(唯一接受執行,順便說一句)要麼曲解「失敗」,以包括刪除功能的選擇,或適用[over.match.funcs]/8太鬆懈了。查看錯誤31025

+0

謝謝。類似'return const_cast (P);'修復了錯誤 - 但是這有副作用嗎? –

+1

@HBellamy首先,它會阻止複製elision被應用。您是否有任何具體原因*刪除*移動ctor而不是簡單地不提供它?你意識到不自己提供一個意味着,在你的情況下,沒有一個會被隱式聲明?參見[\ [class.copy.ctor \] /(8.1)](http://eel.is/c++draft/class.copy.ctor#8.1)。 – Columbo

4

Wandbox上的所有GCC版本均拒絕此代碼。你是否有機會在Mac上測試它,並使用它的Clang-masquerading-as-GCC?

這與P0135無關。鏘是簡單地把一個過度自由的閱讀「失敗」在什麼是目前[class.copy.elision]/3,它說,在這種情況下

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.

這重載不會失敗;它成功並選擇了正在被刪除的移動構造函數。這應該是事情的結局。

這已報告爲bug 31025

+0

@columbo有何反應? –

+0

@HBellamy說什麼?我相應地修改了我的答案。 – Columbo