如何迭代地找到几个名称在C ++中只有数字不同的变量?

时间:2009-02-19 18:44:22

标签: c++ variables naming

我需要一个帮助我的方法,在循环中逐个到达每个名为“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'的东西,但谷歌没有给出任何匹配的东西。我也尝试使用运算符##预处理名称,但似乎没有办法将当前整数值放到宏中。

9 个答案:

答案 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();
}