【问题标题】:C++ function throws error when I use a header, but not if I define it in source?当我使用标头时,C++ 函数会引发错误,但如果我在源代码中定义它则不会?
【发布时间】: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 获胜。谢谢大家!

标签: c++ function vector header definition


【解决方案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);
      

      尽量避免在头文件中使用命名空间以避免名称冲突。

      【讨论】:

        猜你喜欢
        • 2014-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多