带有矢量的 LNK2005 错误

Posted

技术标签:

【中文标题】带有矢量的 LNK2005 错误【英文标题】:LNK2005 error with vector 【发布时间】:2012-07-25 20:58:03 【问题描述】:

此博客Cubic 建议尝试四件事,然后或多或少地寻求帮助

重建,检查 检查运行时库,只有一个项目 检查入口点,检查 SUBSYSTEM:CONSULE 检查强制包含的 .lib 文件,我没有看到 #pragma comment(lib, ...) 关于在链接器选项中打开 /VERBOSE 的问题,我没有看到该选项

我会发布一些代码,但这是一个 LNK 错误;它没有提供太多信息。

LNK2005:“类 std::vector,类 std::allocator >,类 std::allocator,类 std::allocator > > >,类 std::allocator,类 std::allocator >,类 std: :allocator,class std::allocator > > > > > list1" (?list1@@3V?$vector@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@ D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@V? $allocator@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits @D@std@@V?$allocator@D@2@@std@@@2@@std@@@2@@std@@A) 已在 msproject.obj 中定义 LNK2005:“类 std::vector,类 std::allocator >,类 std::allocator,类 std::allocator > > >,类 std::allocator,类 std::allocator >,类 std: :allocator,class std::allocator > > > > > list1" (?list1@@3V?$vector@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@ D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@V? $allocator@V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits @D@std@@V?$allocator@D@2@@std@@@2@@std@@@2@@std@@A) 已在 msproject.obj 中定义

我看到它与 msproject 中已经定义的向量有关 - 我确保向量具有不同的名称。这是带有标题# include <vector> 的东西吗?我尝试注释掉一些#includes 以检查,但相同。

【问题讨论】:

【参考方案1】:

似乎您不止一次定义了list1。 (顺便说一句,顾名思义应该是std::list,但这超出了问题的范围)

你有没有

std::vector<std::string> list1;

在头文件中?该标题是否包含在多个翻译单元中?

如果要全局,需要在头部使用extern

extern std::vector<std::string> list1;

并将定义移动到单个实现文件中。

【讨论】:

@Luchian_Grigore for std:: 我声明'使用命名空间 std;'是的,vector> list1;在标题中声明。 “单个实现文件”是什么意思,什么是“翻译单元”,我正在查找这些术语?尝试外部。 @forest.peterson 好的,完美。那是你的问题。简单地说,翻译单元就是一个包含所有内容的cpp 文件。实现文件是cpp 文件。基本上,您必须将标头中的定义复制到 cpp 文件中,并在标头中使用 extern 声明变量。 @Luchian_Grigore LNK2005 已消失,但现在该向量未在 main.cpp 之外声明;我在 main.cpp 中将向量声明为 list1 和 list2 以及一个解决此问题的类。 @forest.peterson 您是否将extern 后跟声明放在标题中?如果您想在不同的文件中使用该向量,只需在声明中包含标头即可。 @forest.peterson 这个问题中的问题是多重定义,您可以通过声明变量 extern 并只定义一次来解决这个问题。 C2071 是编译器错误,不一样。【参考方案2】:

您已经多次定义了 list1。可能通过将它放在一个头文件中,然后您将其包含在多个 cpp 文件中。你应该这样做

// in header file
extern std:vector<whatever> list1;

// in one cpp file
std:vector<whatever> list1;

您的知识差距在于您不知道/不了解如何在具有多个源文件的程序中声明和定义全局变量。任何一本不错的 C++ 入门书籍都应该涵盖这一点。

【讨论】:

@Luchian Grigore 很抱歉,您可能会觉得这很难相信,但是当我开始发帖时,您的帖子是不可见的。显然我一定是个打字慢的人。否决你认为抄袭你的人有点可悲,这不是竞争。 不打算开始辩论。我解释了我的反对意见,因为我想鼓励您继续使用 SO(因为您是新用户),这是爱的夏天。但不鼓励重复答案。此外,如果您的打字员 那么 慢(10 分钟 5 行),您可以简单地删除此答案,您的代表不会受到反对票的影响。毕竟,这不是比赛,对吧? 在这个化身中是新的,对 SO 来说并不是新的。我没有看到任何删除我的帖子的方法。也许我还没有足够的权限。 我投了赞成票,因为虽然大部分都是重复的,但我在正确的轨道上使用了关于在标头中声明一次与 extern 和一次在 cpp 中 - 结果是,它在 cpp A 中一次作为 extern 一次在cpp B. 这行得通,但通常认为将 extern 声明放在头文件中会更好。假设您需要在多个 cpp 文件中使用该变量,则必须重复 extern 声明。更糟糕的是,假设您重复了 extern 声明,但随后您决定需要更改它,您将不得不在多个地方进行相同的更改。更糟糕的是,假设你弄错了,你最终得到了同一个全局变量的多个不兼容的声明。随着程序变得越来越大,这样的问题变得越来越令人担忧。

以上是关于带有矢量的 LNK2005 错误的主要内容,如果未能解决你的问题,请参考以下文章

C/C++ 混合程序中的错误 LNK2005 和错误 LNK2019

error:LNK2005 已经在*.obj中定义

LNK2005:删除 VC++ 中已定义的错误

Visual Studio 错误 LNK2005

C++ 链接器错误 - 错误 LNK2005: ... 已定义

LNK2005 错误,因为我有两个并行运行的 c++ 窗口