【问题标题】:Why do I get a reference to namespace is ambiguous error?为什么我得到对命名空间的引用是不明确的错误?
【发布时间】:2021-03-26 18:31:19
【问题描述】:

我有两个模块,我将它们分成两个不同的.h.cpp 文件。我想在同一个命名空间中声明这两个模块,但我收到错误candidate found by name lookup is 'my_namespace'error: reference to 'my_namespace' is ambiguous。为什么会这样?

我在下面列出了我的 cmake 配置、两个头文件和 module_b 源文件。

file(
    GLOB HEADER_LIST CONFIGURE_DEPENDS 
    "${myproj_SOURCE_DIR}/include/myproj/*.h"
)

# Make an automatic library - will be static or dynamic based on user setting
add_library(
    ${CMAKE_PROJECT_NAME}
    module_a.cpp
    module_b.cpp
    ${HEADER_LIST}
)

target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ../include)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ./)

# All users of this library will need at least C++17
target_compile_features(${CMAKE_PROJECT_NAME} PUBLIC cxx_std_17)

// module_a.h
namespace my_namespace { // << note: candidate found by name lookup is 'my_namespace'
    struct My_Struct_A {
        int a;
    };
}
// module_b.h
#include <my_proj/module_a.h>

namespace my_namespace { // << note: candidate found by name lookup is 'my_namespace'
    struct My_Struct_B {
        int b;
        My_Struct_A ab;
    };

    My_Struct_B do_something();
}
// module_b.cpp
#include <my_proj/module_b.h>

my_namespace::My_Struct_B my_namespace::do_something() { // << error: reference to 'my_namespace' is ambiguous
    return My_Struct_B { 1, { 2 } };
}

【问题讨论】:

  • 这些“模块”是软件子组件意义上的,还是C++20“模块”意义上的?它看起来像前者,但如果您尝试使用后者,您可能会得到多个不同的命名空间。
  • 这个错误是只有在使用cmake时才会出现,还是手动写出编译命令行时也会出现?
  • 请注意,您可能可以通过写::my_namespace::do_something来解决您的问题
  • @BenVoigt 抱歉,这只是软件模块;我正在使用 c++17。我实际上没有尝试过没有 CMake,但 CMake 只是使用常规编译步骤,所以我认为这无关紧要。在命名空间之前添加全局解析标识符也无济于事。
  • 干净编译(我假设有一个错字已修复)-godbolt.org/z/976M3rdd5

标签: c++ cmake


【解决方案1】:

返回值My_Struct_Bmy_namespace 中声明,因此您需要对其进行限定:

my_namespace::My_Struct_B my_namespace::do_something() {
    return My_Struct_B { 1, { 2 } };
}

错误消息在技术上是正确的,但有点误导。

或者(感谢@Eljay):

namespace my_namespace {

My_Struct_B do_something() {
    return My_Struct_B { 1, { 2 } };
}

}

【讨论】:

  • 虽然我自己是这样做的,但我承认这是在命名空间中进行定义的原因之一,而不是将定义限定在命名空间中。
  • 这只是我的一个错字;我确实在返回类型上有了分辨率限定符,错误仍然存​​在。
  • 另一个选项是尾随返回类型:auto my_namespace::do_something() -&gt; My_Struct_B { ... }do_something 的定义中,命名空间在范围内。
猜你喜欢
  • 1970-01-01
  • 2014-04-09
  • 2023-03-12
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 2012-05-07
  • 2010-09-06
  • 2018-11-22
相关资源
最近更新 更多