簡體   English   中英

為什么GCC沒有給我一個錯誤

[英]Why isn't GCC giving me an error

對於我希望的示例,GCC並沒有給我一個錯誤:

class CannotBeCopied {
public:
    CannotBeCopied(const CannotBeCopied&) = delete;
    CannotBeCopied& operator=(const CannotBeCopied&) =delete;
    CannotBeCopied() { }
    ~CannotBeCopied() { }
};

template<class T>
class FirstVector {
public:
    FirstVector() {
        size = 1;
        data = new T[size];
    }

    ~FirstVector() {
        delete[] data;
    }

    FirstVector(const FirstVector& source) {
        size = source.size;
        data = new T[size];
        for(int k=0;k!=size;k++) {
            data[k] = source.data[k]; //<--I EXPECT AN ERROR HERE
        }
    }
private:
    int size;
    T* data;
};

當不使用復制構造函數時,不會發生此錯誤(也就是說,在使用復制構造函數時,確實會發生此錯誤)。

由於有了模板,我不能簡單地將copy-ctor移到代碼文件中,並且在編譯時會失敗。

我怎樣才能使它失敗?

這不是SFINAE,它應該無法實例化模板。 如果copy-ctor本身是模板方法(例如:

template<class U=T>

在上面的那一行,那就是SFINAE。

我正在使用GCC 4.8.1, -pedantic -Wall -Wextra-std=c++11

我希望通過以下操作使它失敗:

int main() { 
    FirstVector<CannotBeCopied> whatever;
}

我知道GCC只是懶惰而不必做它不需要做的工作,但是我不喜歡如果我要在代碼文件中顯式實例化此模板,則會收到錯誤消息。 有沒有辦法得到我想要的錯誤?

如果您實際上並未創建模板的實例,則無需調用復制構造函數-如果不使用,則甚至不會為CannotBeCopied創建模板代碼。 調用復制構造函數,您將得到錯誤:

 FirstVector<CannotBeCopied> a;
 FirstVector<CannotBeCopied> b = a;

編輯:您還可以通過添加所有模板的成員來使用模板的顯式實例化

template class FirstVector<CannotBeCopied>;

(語言規范的第14.7.2節)

C ++中的模板只有在使用時才會實現 其他一切都太昂貴了。

您可能已經聽說過,C ++模板正在完善中,因此評估它們可能非常昂貴。 IIRC上有一個Fibonnaci <17>的示例,它將使編譯器計算該數字...

特別是,這意味着將消除死代碼,並且僅當您嘗試使用復制構造函數時,c ++編譯器才會失敗。

這不僅僅是海灣合作委員會懶惰的問題; 絕對禁止它按照標准執行您想要的操作。 [temp.inst] / p1、2、11:

1除非已經明確實例化了類模板專業化(14.7.2)或明確了專門化(14.7.3),否則在需要完全定義的對象類型的上下文中引用該專業化時,將隱式實例化該類模板專業化。類類型的完整性會影響程序的語義。 [...]類模板專業化的隱式實例化導致聲明的隱式實例化,而不是類成員函數的定義,默認參數或異常規范的隱式實例化。[...]

2除非已明確實例化或顯式實例化了類模板或成員模板的成員,否則在需要成員定義存在的上下文中引用專門化時,將隱式實例化成員的專門化。 [...]

11實現不得隱式實例化不需要實例化的類模板的函數模板,變量模板,成員模板,非虛擬成員函數,成員類或靜態數據成員。

這使您可以使用例如std::vector的僅移動類型。 它們的副本構造函數將不會編譯,但是只要您不使用它們, std::vector<std::unique_ptr<T>>就是完全有效的。

要強制它失敗,您可以在FirstVector內部使用static_assert

static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible");

但是請注意,這僅檢查副本構造函數的聲明是否可訪問且未被刪除,而不檢查副本構造函數的主體將進行編譯,這意味着它將錯誤地報告std::vector<std::unique_ptr<T>>是可復制構造的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM