2

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

在过去的 1h 30m 中,我通过 StackOverflow 和 Google 进行了搜索,但找不到任何有用的信息。

简而言之,我一直在使用一个已在头文件中初始化并设置的数组。使用 s 转换此代码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

4 回答 4

4

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

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 有一个,用于更通用地初始化和分配 2011 之前的容器。

于 2013-11-13T15:37:44.123 回答
2

您不能在函数外使用表达式语句。此外,将矢量放在标题中也是一个坏主意。如果您使用初始化程序列表而不是 push_back 方法,则可以避免错误。例如

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
};
于 2013-11-13T15:37:41.517 回答
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
    // ...
}
于 2013-11-13T15:36:13.060 回答
0

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

此外,还有一些关于编码风格的评论:

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

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

于 2013-11-13T15:34:22.937 回答