容器初始化方式?
Container initialization ways?
我的编译器不支持 C++11.
事实证明,没有简单的方法来初始化标准库容器的元素。例如,如果你想初始化一个字符串向量,你通常会像这样使用一系列 push_back()
调用:
// file.h
void init_input_tbl(vector<string>& tbl){
tbl.push_back("jan");
tbl.push_back("feb");
tbl.push_back("mar");
tbl.push_back("apr");
tbl.push_back("may");
tbl.push_back("jun");
tbl.push_back("jul");
tbl.push_back("aug");
tbl.push_back("sep");
tbl.push_back("oct");
tbl.push_back("nov");
tbl.push_back("dec");}
vector<string>month_input_tb
// file.cpp
main(){
init_input_tbl(month_input_tb);
//...
Q1。在 C++03 中是否有另一种初始化容器的方法?
除此之外,当我尝试初始化时,在头文件或全局环境中使用函数 init_input_tbl()
,它显示以下错误:this declaration has no storage class or type specifier
.
Q2。在 file.h
或全局环境中使用 init_input_tbl()
初始化矢量 month_input_tb
有什么方法或技术?
全局的替代方法是创建一个函数,returns 您要在初始化中使用的值:
std::vector<std::string> month_inputs();
std::vector<std::string> month_input_tb = month_inputs();
然后在 cpp 中(或者 header 如果你使这个内联)你可以定义函数:
std::vector<std::string> month_inputs() {
std::vector<std::string> result;
result.push_back(...);
...
return result;
}
如果您可以引入一些额外的依赖项,您可以使用已经提供此类功能的 boost assign:
std::vector<std::string> month_inputs_tb = list_of<std::string>()("One")("Two");
如果您想避免在主 cpp 文件中进行任何类型的初始化,您最好的选择是使用编译器特定库 init/constructor,例如 MSVC 中的 DllMain
或 g++ 中的 __attribute__((constructor))
。我相信在 c++ 程序范围内不能保证静态 class 成员的初始化顺序。
例如g++:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
__attribute__((init_priority(1000)))
vector<string> myvect;
__attribute__((constructor(1001)))
void myvectinit() {
myvect.push_back("abc");
myvect.push_back("def");
myvect.push_back("ghi");
}
int main() {
cout << myvect.size() << endl; // output: 3
return 0;
}
首先,像在 header 中那样声明一个全局变量,而没有 static
或 class 一起声明,是一个坏主意。如果 header 包含在多个 .cpp
文件中,您将遇到编译器问题。
您的问题的一个解决方案是使用单例模式。 class 具有可由函数获取的静态变量,该函数在第一次调用函数时被初始化。
David Rodriguez 的解决方案也有效,但您将回到只能包含在 one 源中的 header 文件的问题文件。但是如果你这样做的话:
//utils.h
struct utils {
static std::vector months_inputs_tb;
};
//utils.cpp
#include "utils.h"
std::vector month_inputs() {
...
}
utils::months_inputs_tb = month_inputs();
//code.cpp
#include "utils.h"
//use utils::months_input as you want
然后你可以在多个.cpp
文件中自由包含包含months_inputs_tb
的header。
我假设您的目标只是一种初始化复杂 objects(例如 vector
)的简便方法。 (我不明白你为什么关心代码的位置,headers 与 cpp 文件)。
有了这个帮手:
template<size_t N, typename T>
vector<T> construct_vector(const T (&init)[N]) {
vector<T> tbl;
for(size_t i=0; i<N; ++i) {
tbl.push_back( init[i] );
}
return tbl;
}
你可以像这样构造你的向量:
vector<string> month_input_tb = construct_vector((string[]) {"jan","feb"
,"mar","apr","may","jun","jul","aug","sep","oct","nov","dec"});
之所以有效,是因为您只是在使用 string
。更复杂的向量objects可能会更难。
我的编译器不支持 C++11.
事实证明,没有简单的方法来初始化标准库容器的元素。例如,如果你想初始化一个字符串向量,你通常会像这样使用一系列 push_back()
调用:
// file.h
void init_input_tbl(vector<string>& tbl){
tbl.push_back("jan");
tbl.push_back("feb");
tbl.push_back("mar");
tbl.push_back("apr");
tbl.push_back("may");
tbl.push_back("jun");
tbl.push_back("jul");
tbl.push_back("aug");
tbl.push_back("sep");
tbl.push_back("oct");
tbl.push_back("nov");
tbl.push_back("dec");}
vector<string>month_input_tb
// file.cpp
main(){
init_input_tbl(month_input_tb);
//...
Q1。在 C++03 中是否有另一种初始化容器的方法?
除此之外,当我尝试初始化时,在头文件或全局环境中使用函数 init_input_tbl()
,它显示以下错误:this declaration has no storage class or type specifier
.
Q2。在 file.h
或全局环境中使用 init_input_tbl()
初始化矢量 month_input_tb
有什么方法或技术?
全局的替代方法是创建一个函数,returns 您要在初始化中使用的值:
std::vector<std::string> month_inputs();
std::vector<std::string> month_input_tb = month_inputs();
然后在 cpp 中(或者 header 如果你使这个内联)你可以定义函数:
std::vector<std::string> month_inputs() {
std::vector<std::string> result;
result.push_back(...);
...
return result;
}
如果您可以引入一些额外的依赖项,您可以使用已经提供此类功能的 boost assign:
std::vector<std::string> month_inputs_tb = list_of<std::string>()("One")("Two");
如果您想避免在主 cpp 文件中进行任何类型的初始化,您最好的选择是使用编译器特定库 init/constructor,例如 MSVC 中的 DllMain
或 g++ 中的 __attribute__((constructor))
。我相信在 c++ 程序范围内不能保证静态 class 成员的初始化顺序。
例如g++:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
__attribute__((init_priority(1000)))
vector<string> myvect;
__attribute__((constructor(1001)))
void myvectinit() {
myvect.push_back("abc");
myvect.push_back("def");
myvect.push_back("ghi");
}
int main() {
cout << myvect.size() << endl; // output: 3
return 0;
}
首先,像在 header 中那样声明一个全局变量,而没有 static
或 class 一起声明,是一个坏主意。如果 header 包含在多个 .cpp
文件中,您将遇到编译器问题。
您的问题的一个解决方案是使用单例模式。 class 具有可由函数获取的静态变量,该函数在第一次调用函数时被初始化。
David Rodriguez 的解决方案也有效,但您将回到只能包含在 one 源中的 header 文件的问题文件。但是如果你这样做的话:
//utils.h
struct utils {
static std::vector months_inputs_tb;
};
//utils.cpp
#include "utils.h"
std::vector month_inputs() {
...
}
utils::months_inputs_tb = month_inputs();
//code.cpp
#include "utils.h"
//use utils::months_input as you want
然后你可以在多个.cpp
文件中自由包含包含months_inputs_tb
的header。
我假设您的目标只是一种初始化复杂 objects(例如 vector
)的简便方法。 (我不明白你为什么关心代码的位置,headers 与 cpp 文件)。
有了这个帮手:
template<size_t N, typename T>
vector<T> construct_vector(const T (&init)[N]) {
vector<T> tbl;
for(size_t i=0; i<N; ++i) {
tbl.push_back( init[i] );
}
return tbl;
}
你可以像这样构造你的向量:
vector<string> month_input_tb = construct_vector((string[]) {"jan","feb"
,"mar","apr","may","jun","jul","aug","sep","oct","nov","dec"});
之所以有效,是因为您只是在使用 string
。更复杂的向量objects可能会更难。