2016-02-13 65 views
4

考慮下面的代碼:參考預選賽和刪除的成員方法

#include<utility> 

struct S { 
    void f(int) = delete; 
    void f(int) && { } 
}; 

int main() { } 

它不會編譯說的成員方法不能重載是有意義的,當然。

另一方面,下面的代碼編譯:

#include<utility> 

struct S { 
    void f(int) & = delete; 
    void f(int) && { } 
}; 

int main() { 
    S s; 
    // s.f(42); <-- error, deleted member method 
    std::move(s).f(42); 
} 

那是合法的代碼?
在同一個類中定義兩個完全不同的接口是不可能的,前者用於左值,後者用右值?
除了它沒有太大意義的事實,但它真的傷害了我。
不應該刪除的功能作爲一個整體刪除,而不是刪除只有當你是一個左值
這個功能的目的是什麼?這是經典的晦澀的角落案例還是有更多我看不到的東西?

+0

副作用:void f(int)&= delete;'是多餘的。一旦你定義了一個右值重載函數,左值不會被生成,所以你必須明確地提供它(當然還有其他方法)。 – vsoftco

+1

@vsoftco這確實回答了我的問題,這是合法的。 :-) – skypjack

+0

我可以看到一個用例:'operator&'您可能只想刪除右值版本來禁止獲取臨時地址,否則允許獲取地址。 – koraxkorakos

回答

6

如果對象是l-r值,有時可以禁止某些操作。

想象一下FILE*的RAII包裝。它在構造函數中打開文件,在析構函數中關閉它,將需要手動控制的C特性轉換爲C++異常安全類。要與C接口交互,有一個.get()成員返回原始指針。有人可能會這樣寫:

FILE* file = CFile("file.txt").get();

這將編譯,但它是錯誤的:文件將盡快關閉,因爲file變量將被初始化。如果你刪除了一個r值超載(從不首先提供),那麼它會導致編譯時錯誤,並使我們免於尋找bug。

+0

以外的東西。謝謝!! – skypjack