【问题标题】:Error 'initializer does not name a non-static data member or base class' when the initializer is the base class name当初始化程序是基类名称时,错误“初始化程序没有命名非静态数据成员或基类”
【发布时间】:2020-05-02 04:39:40
【问题描述】:

我面临以下问题。在文件 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 继承时,我希望编译器会给我一个错误,但事实并非如此。

谁能解释一下原因?

提前谢谢你。

【问题讨论】:

  • 认为std::exception派生的名称exception(不合格)进入Exception的范围,但我不知道在哪里查看此规则的标准。
  • 你使用struct而不是class有什么原因吗?
  • @anastaciu 不是特别是,但我看不出使用类而不是结构的原因。
  • 可能是您没有#included 异常标头吗? #include &lt;exception&gt;#include "exception.h" 都将包含 std::exception
  • @jiveturkey 不,我已经包含了正确的,否则当我指定Exception 类的全名时它不会编译。

标签: c++ inheritance namespaces


【解决方案1】:

@molbdnilo 建议存在名称查找问题。问题在于名称“异常”用于命名空间异常和标准::异常结构。我从您发布的代码中删除了代码和 cmets。

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
    };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    相关资源
    最近更新 更多