【问题标题】:include file error in C++在 C++ 中包含文件错误
【发布时间】:2009-11-22 22:14:03
【问题描述】:

问题已解决!非常感谢您的建设性建议!

我无法弄清楚以下代码中的错误是什么。我做包括的方式有什么问题吗?

// This is utils.h
#ifndef UTILS_H
#define UTILS_H

#include <iostream>
#include <fstream>
#include <stack>
#include <queue>
#include <vector>
#include <list>
#include <string>
#include <algorithm>

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vii> vvii;
typedef stack<int> si;
typedef queue<int> qi;

#define tr(c,i) for(typeof((c).begin()) i = (c).begin() ; i!=(c).end() ; ++i )
#define all(c) (c).begin(),(c).end()
#define cpresent(c,x) (find(all(c),x) != (c).end())

#endif

// ==============================================================
// Below is main.cpp

#include "utils.h"

int main() {
    vi v;
}

在编译“g++ main.cpp”时,我收到以下错误消息:

utils.h:13:错误:“

这段代码有什么问题?当我没有#ifndefs 时,utils.h 过去可以正常工作。

【问题讨论】:

  • 一种代码混淆工具,IMO。我可以理解特定于程序的 typedef,例如 typedef std::vector&lt;std::string&gt; NameList;。此外,cpresent 也可以是一个内联函数。而不是 tr,BOOST_FOREACH 应该更便携(或者找一个支持 C++0x 的基于范围的 for 循环的编译器)。
  • 我无法使用 BOOST。如果您可以为 vector 建议一个比键入 vector 本身更短的更好的 typedef,我将很高兴。
  • Typedef 主要不是为了减少输入,而是为了 a) 更具描述性的名称,b) 助记符的原因和 c) 如果在任何地方显式声明类型,您可以更轻松地在类型之间切换。
  • 取决于向量的用途。如果是年龄列表,那么typedef std::vector&lt;int&gt; age_list; 不要编写程序试图保存击键,编写程序以增加可读性和解决问题。

标签: c++ compiler-errors


【解决方案1】:

这些类型(pairstackqueuevector 等)位于 std 命名空间中。您要么需要在文件顶部添加 using namespace std;(通常在所有标准库包含之后),要么通过在它们前面添加 std:: 来完全限定类型名称。

一般来说,完全限定类型名称比使用using namespace 更好,以避免名称之间的潜在冲突并使代码更简洁。你应该永远不要在头文件中使用using namespace std

(按照简洁的代码行,您应该考虑为您的类型使用更好、更长的名称;iiviivvii 是糟糕的类型名称)。

【讨论】:

    【解决方案2】:

    vector 等包含在命名空间std:: 中。请不要在头文件中使用using namespace std;。否则,包含它的每个人都会得到所有std::,无论是否有意。

    附带说明,如果这是一个旨在包含在其他文件中的实用程序标头,您可以将这些类型和#define 包装在一个命名空间中。注意#define's 不尊重命名空间,所以你会改为前缀:

    namespace utility
    {
        // ...
        typedef std::queue<int> qi;
    
        // most would recommend this be in CAPS
        #define utility_tr(c,i) for(typeof((c).begin()) i = (c).begin() ; i!=(c).end() ; ++i )
        // ...    
    }
    

    【讨论】:

    • +1 建议他将代码放入命名空间;绝对是个好建议。
    【解决方案3】:

    在你的 typedef 之前,你应该有 using namespace std;

    此外,您可能希望使用比 UTILS_H 更不常见的名称。

    【讨论】:

    • 不,他不应该。他应该完全限定它们,因为这是一个头文件。 (而且因为using namespace std; 通常是不好的做法)
    【解决方案4】:

    你应该写

    using namespace std;
    

    行前

    typedef pair<int,int> ii;
    

    或使用std::完全限定stl类型

    【讨论】:

    • 大多数情况下使用命名空间std;足够了。虽然使用 std:: 运算符提供了更好的变量阴影(特别是如果您使用欧几里德向量),但它通常是不必要的并且会导致代码混淆。还值得注意的是,#include 是命名空间版本,#include 不是,因此是一种有效的替代解决方案(尽管我不推荐)。
    • std:: 不是运算符; :: 是一个操作员。 vector.h 不是 C++ 标准的一部分。
    • @tzenes:我更喜欢使用 std::-prefix。但是,由于问题的作者喜欢像 ii、vi、vii 这样的名字,我认为最好使用 'using namespace std' 来保持一致性:)
    • 如果你能告诉我用什么来代替 vi,它比编写 vector 本身更短,但与 vector 一样可读,那么我很乐意使用它。除了少写之外,我没有看到使用 typedef 的任何理由。
    • IntVectorIntVec 是不错的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多