簡體   English   中英

當初始值設定項是基類名稱時出現錯誤“初始值設定項未命名非靜態數據成員或基類”

[英]Error 'initializer does not name a non-static data member or base class' when the initializer is the base class name

我面臨以下問題。 在文件my_exception.h 中,我定義了我自己的繼承自std::exception的異常類:

// File "my_exception.h"
#include <exception>
#include <string>

namespace proj { namespace exception {

struct Exception : public std::exception {
    explicit Exception(const std::string& msg) noexcept : msg_(msg) { }

    inline const char* what() const noexcept override { return msg_.c_str(); }

private:
    std::string msg_;
};

} }

然后我在另一個命名空間中定義了一個名為BadParameterAccess的派生異常類,分別在.h.cpp文件中拆分聲明和實現:

// File parameter_exception.h
#include "exception.h"

namespace proj { namespace parameter {

struct BadParameterAccess final : public exception::Exception
{
    BadParameterAccess() noexcept;
};

} }

// File parameter_exception.cpp
#include "parameter_exception.h"

namespace proj { namespace parameter {

BadParameterAccess::BadParameterAccess() noexcept
    : exception::Exception("[BadParameterAccess] parameter not set yet."){ }

} }

我嘗試使用多個編譯器編譯此代碼。 使用 clang 6.0 我收到以下錯誤:

parameter_exception.cpp:7:18: error: initializer 'Exception' does not name a non-static data member or base class; did you mean the base class 'Exception'?
    : exception::Exception("[BadParameterAccess] parameter not set yet."){ }
                 ^~~~~~~~~
                 Exception
./parameter_exception.h:11:35: note: base class 'exception::Exception' specified here
struct BadParameterAccess final : public exception::Exception
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~

g++ 7 給出了一個等效的錯誤,Visual Studio 2017 給出了以下錯誤:

parameter_exception.cpp(8): error C2039: 'Exception': is not a member of 'std::exception'

代碼在以下任一情況下都能完美編譯:

  1. 在文件parameter_exception.cpp 中,我指定了基類初始值設定項( proj::exception::Exception )的完整路徑,或者
  2. 在文件parameter_exception.cpp 中,我從基類初始值設定項( Exception )中刪除命名空間,或者
  3. 在文件my_exception.h 中,我從std::exception刪除了繼承,或者
  4. 我以其他方式重命名我的命名空間exception

據我從我得到的不同錯誤中了解到,編譯器希望在類std::exception而不是在命名空間exception找到一個名為Exception的成員,但我不明白為什么會發生這種情況。 此外,當我首先從頭文件parameter_exception.h中的exception::Exception繼承時,我本來希望編譯器給我一個錯誤,但它沒有。

有人可以向我解釋原因嗎?

先感謝您。

正如@molbdnilo 所暗示的那樣,名稱查找存在問題。 問題在於名稱“異常”被用於命名空間異常和標准::異常結構。 我從您發布的代碼中刪除了代碼和注釋。

namespace standard {
    struct exception{
        explicit exception() noexcept { }
    };
}
namespace exception {
    struct A: public standard::exception {
        explicit A() noexcept { }
    };
}
namespace parameter {
    struct BadParameterAccess final : public exception::A
    {
        //BadParameterAccess() noexcept : exception::A() { }; // KO
        BadParameterAccess() noexcept : ::exception::A() { }; // OK
    };
}

namespace standard1 {
    struct exception1{
        explicit exception1() noexcept { }
    };
}
namespace exception2 {
    struct A: public standard1::exception1 {
        explicit A() noexcept { }
    };
}
namespace parameter1 {
    struct BadParameterAccess1 final : public exception2::A
    {
        BadParameterAccess1() noexcept : exception2::A() { }; // OK
        //BadParameterAccess1() noexcept : ::exception2::A() { }; // OK
    };
}

暫無
暫無

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

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