c++ - Visual C:命名空间范围错误或晦涩难懂的功能?
问题描述
您将需要三个不同的文件:header.h
、source.cpp
& main.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
在其中找到标识符。因为您在 namespace 中A
,并且 namespaceA
已将所有命名空间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
。
因此,您所拥有的是一个标题,上面写着“我保证某人,某处将定义A::B::g
”,但实际上没有人这样做。source.cpp
only defined A::g
,它main.cpp
不尝试调用(因为它不知道它存在)。
因此链接器错误。
推荐阅读
- node.js - 为什么所有这些新语言都有自己的网络服务器?
- node.js - Node.js 管道图像到内存并显示它
- c - 在c中的for循环中将int counter转换为char
- javascript - 无法将 JSON 数据或 javascript 函数转换为 HTML
- html - 我无法让 CSS flex 在移动设备上叠加
- visual-studio-code - TreeView 而不是 WebView?
- sql-server - SQL Server 总和查询每 06:30 AM
- python - 方法在启动程序时自动调用
- arrays - 处理 HIVE AVRO 格式表的列值中的新行 - 包含复杂数据类型和嵌套数组
- android - libmonosgen-64bit-2.0.so 未经授权访问“/system/lib64/libsqlite.so” Android 8.1