当我使用标头时,C++ 函数会引发错误,但如果我在源代码中定义它则不会?
Posted
技术标签:
【中文标题】当我使用标头时,C++ 函数会引发错误,但如果我在源代码中定义它则不会?【英文标题】:C++ function throws error when I use a header, but not if I define it in source? 【发布时间】:2011-08-04 20:05:33 【问题描述】:当我尝试使用多个文件时,我在编译一个函数时遇到了一个奇怪的问题。我把它归结为这个简单的例子:假设我想找到一个整数向量的总和。如果我尝试编译以下代码,它会按预期工作:
#include <vector>
#include <iostream>
using namespace std;
int VectorSum (const vector<int>& values)
int S = 0;
for (int t=0; t < values.size(); t++)
S += values[t];
return S;
int main()
vector<int> values;
values.push_back(-100);
values.push_back(75);
values.push_back(75);
cout << "Total = " << VectorSum(values) << endl << endl;
cin.ignore(1, '\n');
return 0;
但是,如果我尝试使用头文件,它会崩溃(在 Windows XP 的 VS 2010 上编译时出现错误 C4430)。这是另一种方法的代码:
标题:
/* VectorSum.h */
#pragma once
#include <vector>
int VectorSum (const vector<int>& values);
来源:
/* VectorSum.cpp */
#include "VectorSum.h"
#include <vector>
int VectorSum (const vector<int>& values)
int S = 0;
for (int t=0; t < values.size(); t++)
S += values[t];
return S;
实施:
/* Main.cpp */
#include "VectorSum.h"
#include <vector>
#include <iostream>
using namespace std;
int main()
vector<int> values;
values.push_back(-100);
values.push_back(75);
values.push_back(75);
cout << "Total = " << VectorSum(values) << endl << endl;
cin.ignore(1, '\n');
return 0;
如您所见,VectorSum.cpp 中的函数代码与我的第一个 .cpp 文件中的代码相同,因此问题一定出在头文件中。任何想法我做错了什么?
【问题讨论】:
你应该使用std::accumulate (values.begin (), values.end (), 0);
...
我很确定这不是导致错误的原因,但如果您在 .h 中包含 #pragma once
#include <vector>
int VectorSum (const std::vector<int>& values);
^^^^^
见the MSDN page for C4430。它是在声明缺少类型或类型未知时发出的。在您的情况下,vector
由于不合格的名称查找规则,是未知类型。
【讨论】:
哇,真快。错过了这一点,我感觉自己像个白痴——很高兴有另一双眼睛看看。谢谢!【参考方案2】:这是std
命名空间的问题。
将标题中的声明更改为:
int VectorSum (const std::vector<int>& values);
并确保 .cpp 文件中有 using namespace std;
(如您的第一个示例),或者在调用/定义函数时正确使用 std
命名空间。例如,您需要在 VectorSum.cpp
文件中执行这些操作之一。
顺便说一句,请不要添加
using namespace std;
声明到头文件。这将强制将名称空间纳入标头的所有用户的范围内(即使它是间接包含的,因此可能并不明显),这可能不符合他们的需求。
【讨论】:
【参考方案3】:问题确实出在头文件中。你忘了添加
using namespace std;
到标题,因此编译器不知道vector
的含义。
更正的标题:
/* VectorSum.h */
#pragma once
#include <vector>
using namespace std; // This was missing
int VectorSum (const vector<int>& values); // Now OK, the compiler knows vector
【讨论】:
不,不要在标题中使用using namespace std;
!只需使用std::vector
。
-1,将using namespace
放在某个标头的全局范围内真是太糟糕了。
我想说根本不要使用using namespace std;
,但这不是这个问题的意义所在。 OP 似乎在任何地方都在使用这个指令。
因为他从不使用标题? (畸形的除外)
这会将std
命名空间中的所有内容拉入包含 VectorSum.h 的所有内容的全局命名空间中。那是邪恶的。【参考方案4】:
你必须在 VectorSum.h 中为向量指定命名空间:
int VectorSum (const std::vector<int>& values);
【讨论】:
【参考方案5】:添加using namespace std
/* VectorSum.h */
#pragma once
#include <vector>
<--------
//using namespace std;
int VectorSum (const std::vector<int>& values);
尽量避免在头文件中使用命名空间以避免名称冲突。
【讨论】:
以上是关于当我使用标头时,C++ 函数会引发错误,但如果我在源代码中定义它则不会?的主要内容,如果未能解决你的问题,请参考以下文章
当我从 C# 代码调用导入的 C++ 函数时,为啥会引发 AccessViolationException?
使用 pyspark 在某些类中应用函数时引发“PicklingError”错误