簡體   English   中英

錯誤C2797:列出成員初始化列表中的初始化

[英]error C2797 : list initialization inside member initializer list

我正在觀看MVA關於C ++的教程,我在下面提到的代碼是由凱特寫的而不是我。 然而,她似乎沒有編譯顯示任何錯誤,但在我的情況下,我得到以下錯誤:

錯誤1錯誤C2797:'NamedRectangle :: _ name':成員初始化列表中的列表初始化或非靜態數據成員初始化程序未實現c:\\ users \\ abhimanyuaryan \\ documents \\ visual studio 2013 \\ projects \\ kate demos \\ 17 inheritance \\ inheritance \\ namedrectangle.h 12 1繼承

代碼中的第12行來自我的NameRectangle類,它繼承自Rectangle類:

class NamedRectangle :  public Rectangle
{
public:
    NamedRectangle() { }

    NamedRectangle(std::string initial_name, int initial_width, int initial_height)
        : Rectangle{ initial_width, initial_height }, _name{ initial_name } //--> This line
    {}  

std::string get_name() const { return _name; }

private:
    std::string _name;

};

當我從構造函數和_name{initial_name}刪除std::string initial_name時,代碼編譯。 請解釋我,不要把我當作經驗豐富的高級程序員。 我昨天才開始使用C ++。

tl;博士 :凱特答案中的解決方案適用於OP; 解釋不正確。 有問題的代碼實際上是正確的,並且在VS2015中編譯。 錯誤(在VS2013 Update 3中 )是MS如何處理在VS2013 RTM中發現的錯誤的結果(他們實際上沒有通過更新修復它,但是他們確實破壞了一些工作代碼)。 它在VS2015中正確固定。


您的代碼在VS2015中正常運行。 據微軟稱 ,在VS2013中,

是的,我們將這些錯誤插入到Update 3中的編譯器中,因為我們對非靜態數據成員初始化的實現是不完整的。

在VS2013中,成員初始化列表中的列表/支撐初始化也被中斷。 它們的實現問題最好vector說明 ,它有一個initializer_list構造函數,它應該貪婪地匹配任何使用帶有可轉換參數的大括號的初始化,但它不能這樣做:

struct S {
    S() : v1{1} {} // C2797, VS2013 RTM incorrectly calls 'vector(size_type)'

    std::vector<int> v1;
    std::vector<int> v2{1, 2}; // C2797, VS2013 RTM incorrectly calls 
                               // 'vector(size_type, const int &)'
};

編譯器很容易回退到正常的重載分辨率。 它不是使用std::initializer_list構造函數,而是調用size_t構造函數。 正如他們的評論所示,這是錯誤的! 因此,由於它們的實現存在缺陷,Microsoft決定禁用在此上下文中使用支撐初始化的功能。

對於std::string s ,應該沒有問題,因為s{"duh"} 調用std::string(const char*) ,但由於該缺陷,MS無論如何都會出錯。 解決方法是明確使用括號代替括號(或升級到VS2015),如Kate的回答中所述。 但錯誤的正確原因如上所述。

這適用於非靜態數據成員初始化(NSDMI)以及初始化列表。 這個在Visual C ++團隊博客中有更多解釋。 至於為什么VS2013永遠不會修復:

我們最初計划在Visual Studio 2013的更新中修復此錯誤,但從工程角度來看,正確的做法是避免另一個問題,並徹底解決初始化的處理問題。 但是,由於需要修改的基本代碼量,檢修編譯器架構是一項艱巨的任務。 我們無法冒險在更新中創建不兼容性或大錯誤尾部,因此NSDMI的正確實現只能在主要版本中提供。

顯然,修復程序已進入Visual Studio 2015,但永遠不會更新到2013。

詹姆斯和我編寫我們用於MVA日和今天的代碼之間有一個編譯器更改。 發生了什么事

 _name{ initial_name }

被解釋為創建一個初始化列表,其中包含一個項目並使用它來初始化成員變量。 哪個你不能做。

解決方法是切換到圓括號:

 _name(initial_name)

這引起了許多人的混淆,我至少有一個客戶端為此破壞了工作代碼。

我解決了

class Namedrectangle : public Rectan
{
    public:
    Namedrectangle(){}

    Namedrectangle(string intname, int init_width, int init_height) 
         : Rectan{ init_width, init_height }
    {
        this->_name=intname;************
    }

    string get_name() const
    {
        return _name;
    }

    private:
    string _name;
};

我認為不能初始化因為變量無法找到或加載

暫無
暫無

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

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