0

I'm trying to define my array of QLineEdits in my header, however im getting an error of

"Storage class specified for 'edits'."

I have,

header.hh

private: extern QLineEdit edits[8];

source.cpp

   void source::setup()
{
QLineEdit edits[8] = { ui->edit1, ui->edit2, ... };
...
}
easty
  • 35
  • 6
  • Can you provide more code, especially for .h? – Kirill Chernikov Jul 08 '16 at 07:31
  • May be you didn't `#include `? Compiler must know it's size. P.S.: Are you sure you need to use this awful `extern`? – ilotXXI Jul 08 '16 at 07:43
  • @ilotXXI - I have `#include `, and I have extern because otherwise I get many errors of _conversion from QLineEdit to non-scalar type QLineEdit requested_ – easty Jul 08 '16 at 07:52
  • As @KirillChernikov said, provide more code, please. Nothing is clear at present. – ilotXXI Jul 08 '16 at 07:55
  • 1
    You can not make a member variable extern. Please, provide all code of .h file and .cpp file and we try to help you! – Kirill Chernikov Jul 08 '16 at 07:59
  • im not sure what more code you're after, nothing else i have is relevant. I've managed to declare and use the array within the function, though i'm after it across the whole class hence trying to declare it in the header. – easty Jul 08 '16 at 08:04

1 Answers1

2

First of all, forget about extern. You don't need to use it. Period. Really.

The "initialization" you wrote for the edits member is also incorrect. We're in C++11 age, you can assign an initializer list, and this is not C so you shouldn't be using naked C arrays.

Thus, your member definition should be

std::array<QLineEdit*, 2> m_edits;

and you should assign to it as follows:

m_edits = {{ ui.edit1, ui.edit2 }};

Note that you don't really want to hold Ui::Setup through a pointer, even if silly Qt Creator template code does it. Hold it by value.

The following is a complete example:

#include <QtWidgets>
#include <array>

// This is what uic would generate from a simple .ui file.
namespace Ui {
struct Source {
   QLineEdit * edit1, * edit2;
   void setupUi(QWidget * parent) {
      edit1 = new QLineEdit{parent};
      edit2 = new QLineEdit{parent};
   }
};
}

class Source : public QWidget {
   Ui::Source ui;
   std::array<QLineEdit*, 2> m_edits;
public:
   Source() {
      ui.setupUi(this);
      m_edits = {{ ui.edit1, ui.edit2 }};
      Q_ASSERT(m_edits[0] == ui.edit1);
      Q_ASSERT(m_edits[1] == ui.edit2);
   }
};

int main(int argc, char ** argv) {
  QApplication app{argc, argv};
  Source source;
  return 0;
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • There is a significant benefit of a pointer to the UI class - it doesn't need to be fully defined in the header. If you include it by value (or, equivalently, by inheritance), then every time you change the UI file, every user of your widget is a dependency and gets recompiled. So the Qt example code is not at all "silly" for doing that - it's helping decouple the implementation from its interface. – Toby Speight Jul 08 '16 at 14:24
  • @TobySpeight If that's a concern, you should be using a [PIMPL](http://stackoverflow.com/q/25250171/1329652). If you're not using a PIMPL, you're not really concerned about it, since any other change to private interface will cause recompilation of other code. Worse yet, you might end up fighting yourself not to touch the private implementation even if it'd make sense - out of the concern for recompilation cascades. Adding a pointer here or there instead of a PIMPL is ridiculously half-baked. Especially that your PIMPL can be allocation-free if it derives from `QWidgetPrivate`. – Kuba hasn't forgotten Monica Jul 08 '16 at 14:30