gpt4 book ai didi

c++ - 视觉 C : Namespace Scope Bug or Obscure Feature?

转载 作者:太空宇宙 更新时间:2023-11-04 15:55:50 24 4
gpt4 key购买 nike

您将需要三个不同的文件:header.hsource.cppmain.cpp

// header.h
#pragma once

namespace A
{

namespace B
{
class C
{
public: static void f();
};

void g();
}

using namespace B;
}

// source.cpp
#include "Header.h"

namespace A
{
void C::f()
{
#pragma message( "Compiling " __FUNCTION__ )
}

void g()
{
#pragma message( "Compiling " __FUNCTION__ )
}
}

// main.cpp
#include "Header.h"

int main()
{
A::C::f();
A::g();
}

我预计没有错误,相反它看起来像类和函数属于不同的命名空间,尽管在相同的范围内声明和实现:

1 > Source.cpp
1 > Compiling A::B::C::f
1 > Compiling A::g
1 > Generating Code...
1 > ConsoleApplication10.obj : error LNK2019 : unresolved external symbol "void __cdecl A::B::g(void)" ( ? g@B@A@@YAXXZ) referenced in function _main

代码由工具生成。

谢谢

最佳答案

当你这样做时:

  void C::f()
{
#pragma message( "Compiling " __FUNCTION__ )
}

这里的f是一个限定名(由C限定)。因此,C++ 必须弄清楚您在谈论什么 C。为此,它必须查看可用的非限定名称并在其中找到标识符 C。因为您在命名空间 A 中,并且命名空间 A 已将所有命名空间 B 转储到其中,C将解析为 A::B::C。因此,C::f 变为 A::B::C::f

相比之下,当您这样做时:

  void g()
{
#pragma message( "Compiling " __FUNCTION__ )
}

g 是一个非限定名称。因此,该名称的含义正是它所说的:当前命名空间中的名称 g。这是 A

using 声明不会改变当前命名空间;它只会更改名称的名称查找规则。因为 g 是一个非限定名称,所以没有什么可查找的;你的意思是 A::g

这意味着您没有定义函数A::B::g

所以您拥有的是一个 header ,上面写着“我保证有人会在某处定义 A::B::g”,但实际上没有人这样做。 source.cpp 只定义了 A::gmain.cpp 没有尝试调用它(因为它不知道它的存在) .

因此出现链接器错误。

关于c++ - 视觉 C : Namespace Scope Bug or Obscure Feature?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58223555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com