当我使用标头时,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 中包含 ,则无需在包含该 .cpp 的 .cpp 中再次包含它。 H。你可以这样试试吗? @CCC C4430 是编译错误,不是吗?请输入完整的错误文本并告诉我们错误在哪一行。 Armen 获胜。谢谢大家! 【参考方案1】:
#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?

包含标头的 C++ 错误

使用 ISNULL 函数会引发错误

使用 pyspark 在某些类中应用函数时引发“PicklingError”错误

在 python 中使用 cppyy 时,指针变量引发错误为未知类型

为啥当我在函数中声明一个名称为全局数组的局部数组时,bash 会引发未绑定变量警告?