我需要一个帮助我的方法,在循环中逐个到达每个名为“comboBox1”,“comboBox2”等的变量。我想改变代码:
//proceed comboBox1
//proceed comboBox2
//proceed comboBox3
//proceed comboBox4
//proceed comboBox5
//proceed comboBox6
分为:
for (int i = 1; i < numberOfBoxes; i++) {
//proceed comboBox(i)
}
我试图找到类似'eval'的东西,但谷歌没有给出任何匹配的东西。我也尝试使用运算符##预处理名称,但似乎没有办法将当前整数值放到宏中。
答案 0 :(得分:15)
最简单的解决方案是将它们全部放在数组中并使用迭代器:
// I've made up a type, but you get the idea.
std::vector<ComboBox *> combos;
combos.insert(comboBox1);
combos.insert(comboBox2);
combos.insert(comboBox3);
combos.insert(comboBox4);
combos.insert(comboBox5);
combos.insert(comboBox6);
现在你可以迭代组合了。主要问题是c ++没有反射。因此,您无法在运行时生成字符串,并且可以像在其他语言中一样获取对象或函数的地址。
编辑:我刚看到你正在使用Qt。在这种情况下,您应该使用:QList<T> qFindChildren ( const QObject * obj, const QString & name );
或
QList<T> qFindChildren ( const QObject * obj, const QRegExp & regExp);
这使您可以根据运行时生成的名称获取列表。例如:
QList<QComboBox *> combos = qFindChildren(ui, QRegExp("combo[0-9]+"));
那么你可以迭代一遍!
答案 1 :(得分:4)
我知道如何做到的唯一方法是在代码/动态和数组中创建它们。 (不是通过向导)你并不是唯一一个发现MFC(我推测)巫师这个缺点的人。
作为替代方案,如果您的资源在资源文件中是顺序的(我再次假设类似MFC的实现),您可以遍历资源ID以获取资源。这假定它们具有顺序资源ID。我最近使用过这种方法。它工作得很好。不确定它是您正在寻找的还是将与您的GUI一起使用。
答案 2 :(得分:3)
在C ++中,没有任何方法可以在运行时通过名称识别变量。而不是使用一堆具有comboBox1,comboBox2等名称的离散变量,为什么不创建一个可以迭代的ComboBox数组呢?然后你的循环看起来像:
for (int i = 1; i < numberOfBoxes; i++) {
doSomething(comboBoxes[i]);
}
答案 3 :(得分:3)
如果您遇到预处理器黑客,请参阅Boost.Preprocessor库:
// Shamelessly copied from the Boost docs, and only slightly
// adapted. (and probably breaking it ;)
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define DO_SOMETHING(z, n, text) BOOST_PP_CAT(text, n)->DoSomething();
BOOST_PP_REPEAT_FROM_TO(0, 3, DO_SOMETHING, comboBox)
会扩展为:
comboBox0->DoSomething();
comboBox1->DoSomething();
comboBox2->DoSomething();
答案 4 :(得分:2)
我使用以下方法进行功能注册,但您可以尝试在您的情况下应用,希望它保证这种C风格的解决方案不受空格的限制:
#define GET_COMBO_BOX(x,y) x ## y
for (int i = 1; i < numberOfBoxes; i++)
GET_COMBO_BOX(comboBox1,i);
这显然不会做你想要的,因为我在编译时确定并且宏在预处理时花费了,但它会让你知道如何预生成函数调用。
以下是使用宏连接的更完整示例:
#include<iostream>
#include<string>
using namespace std;
template< class E > struct EnumNames
{
static const char* const* names;
static int names_size;
};
#define REGISTER_ENUM( e ) \
const char* const* EnumNames< e >::names = e ## _names; \
int EnumNames< e >::names_size = sizeof( e ## _names ) / sizeof( const char* );
enum ElementType { NEURON, SYNAPSE };
const char* const ElementType_names[] = { "N", "S" };
REGISTER_ENUM( ElementType )
enum TokenMainType { EP, IP, NT, AI };
const char* const TokenMainType_names[] = { "EP", "IP", "NT", "AI" };
REGISTER_ENUM( TokenMainType )
template<class E>
ostream& operator <<(ostream& os, const E& e)
{
if (e > EnumNames< E >::names_size)
cout << "Error" << endl;
os << EnumNames< E >::names[e];
return os;
}
template<class E>
istream& operator >>(istream& is, E& e) {
std::string tmp_e_string;
is >> tmp_e_string;
for (int i = 0; i < EnumNames< E >::names_size; ++i) {
if (tmp_e_string == EnumNames< E >::names[i])
{
e = E(i);
return is;
}
}
cerr << "Fehler: tmp_nntype_string: " << tmp_e_string << endl;
return is;
}
int main (int argc, char **argv)
{
ElementType test1(NEURON);
cout<<string(EnumNames<ElementType>::names[test1])<<endl;
}
答案 5 :(得分:1)
您需要将变量存储在数组中。
E.g
mComboBoxes[MAX_COMBOBOXES];
//初始化
for (int i = 0; i < numberOfBoxes; i++) {
mComboBoxes[i];
}
请注意,数组具有从零开始的索引。
答案 6 :(得分:1)
使用数组。这就是他们的目的。或容器。
T combobox_array[ N ]; // N comboboxes
for (int i = 0; i < N; ++i)
process(combobox_array[ i ]); // note array indices are 0 to N-1
或者,使用STL
vector<T> ca(N);
for_each(ca.begin(), ca.end(), do_something);
答案 7 :(得分:1)
什么是“继续”?
您需要另一级别的间接。也许存储指向您可以在以后迭代的向量中的组合框的指针。
答案 8 :(得分:1)
你有没有理由不能拥有comboBox的数组/向量/列表?
std::vector<ComboBox> comboBoxes;
或者更好地维护一个指向comboBoxes的指针列表?
std::vector<ComboBox*> comboBoxPtrVec;
ComboBox* comboBox1 = new ComboBox();
ComboBox* comboBox2 = new ComboBox();
comboBoxPtrVec.push_back( comboBox1 );
comboBoxPtrVec.push_back( comboBox2 );
for (insigned int i = 0; i < comboBoxPtrVec.size(); ++i)
{
// process comboBox
comboBoxPtrVec[i]->DoSomething();
}