C ++ std :: vector初始化并在头文件中设置

时间:2013-11-13 15:29:52

标签: c++ arrays vector header-files

我目前在我的代码中尝试使用数组在我的头文件中实现std :: vectors时遇到了一些问题。

我在过去的1小时30分内搜索过StackOverflow和Google,但找不到任何有用的信息。

简单地说,我一直在使用已经初始化并在头文件中设置的数组。使用std::vector转换此代码会导致一些问题。

我在(cern)ROOT中进行项目分析,它使用了许多明显的typedef例如。Int_t ==> int

导入的其中一个头文件会自动调用using namespace std;,因此我刚刚关闭了所有std::名称空间。

目前我有:

// file.h
// ...
const Int_t kNpdgCodes = 14;

Int_t pdgCodeID[kNpdgCodes] = {
        0, // other
       22, // photon
      111, // pi0
     -211, // pim
      211, // pip
      221, // eta
      130, // K0L
      310, // K0s
     -321, // Km
      321, // Kp
    -2112, // (a)n
     2112, // n
     2212, // p
     3122  // Lambda
};
// ...

我试图在表单中获取它(或更好,因为没有有用的=构造函数[不能使用C ++ 11]):

// file.h
// ...
vector<Int_t> pdgCodeID;
pdgCodeID.push_back(    0); // other
pdgCodeID.push_back(   22); // photon
pdgCodeID.push_back(  111); // pi0
pdgCodeID.push_back( -211); // pim
pdgCodeID.push_back(  211); // pip
pdgCodeID.push_back(  221); // eta
pdgCodeID.push_back(  130); // K0L
pdgCodeID.push_back(  310); // K0s
pdgCodeID.push_back( -321); // Km
pdgCodeID.push_back(  321); // Kp
pdgCodeID.push_back(-2112); // (a)n
pdgCodeID.push_back( 2112); // n
pdgCodeID.push_back( 2212); // p
pdgCodeID.push_back( 3122); // Lambda
// ...

现在当我编译它(通过ROOT,但无所谓)时,我收到以下错误:

error: expected constructor, destructor, or type conversion before ‘.’ token

表示与push_back对应的每一行。

这是否可以在头文件中? 出了什么问题?

我感谢任何帮助。

4 个答案:

答案 0 :(得分:3)

您不应该在标头中定义,因为如果在多个源文件中包含标头,则会出现多重定义错误。如果你真的想要一个全局,那么在标题中声明它:

extern std::vector<Int_t> pdgCodeID;  // don't use namespace std

并在源文件中定义它:

std::vector<Int_t> pdgCodeID = /* initialiser */;

在C ++ 11中,这很简单:你可以像使用数组一样使用大括号初始化。但由于您出于某种原因没有使用它,最好的选择可能是用函数的结果初始化它:

std::vector<Int_t> make_pdgCodeID() {
    std::vector<Int_t> result;
    result.push_back(0);
    // and so on
    return result;
}

std::vector<Int_t> pdgCodeID = make_pdgCodeID();

或者,Boost有一个library用于初始化和更一般地分配2011年之前的容器。

答案 1 :(得分:2)

您不能在函数外部使用表达式语句。将矢量放在标题中也是一个坏主意。如果不使用push_back方法,您可以使用initilaizer列表来转义错误。例如

vector<Int_t> pdgCodeID = {
        0, // other
       22, // photon
      111, // pi0
     -211, // pim
      211, // pip
      221, // eta
      130, // K0L
      310, // K0s
     -321, // Km
      321, // Kp
    -2112, // (a)n
     2112, // n
     2212, // p
     3122  // Lambda
};

答案 2 :(得分:1)

Juanchopanza是对的,你不能在函数之外调用函数(比如push_back)。您将不得不编写一个初始化变量的函数,如下所示:

//file.h

vector<Int_t> pdgCodeID;

void InitializeCodeID();

然后你需要在cpp文件中定义函数,但是你需要初始化变量。例如:

//file.cpp

void InitializeCodeID()
{
    pdgCodeID.push_back(    0); // other
    pdgCodeID.push_back(   22); // photon
    pdgCodeID.push_back(  111); // pi0
    // ...
}

答案 3 :(得分:0)

这不可能在全局范围内,你需要在某个地方的函数范围内进行。

另外,有关编码风格的几点评论:

  • 您不应该使用using namespace std这是一种糟糕的编码风格,只有在教科书中才能使示例更小,以便更好地适应书籍的页面。而是将std ::说明符用于其中一种用法,为经常使用的东西声明私有类型,或者在标题声明的名称空间内声明私有类型,或者甚至在类中使用更具体的使用using std::vector之类的声明。

  • 你不应该在头文件中定义全局变量,如果头包含在多个源文件中,则会爆炸,而是在头文件中声明全局extern,并创建一个定义和初始化的源文件全球。