PDA

View Full Version : A shortcut please ;)



arcull
21st August 2015, 06:35
Hi, I've got code like


QString *line = new QString[2];
line[0] = setting1;
line[1] = setting2;
FillData(line);

what is the correct syntax to shorten this, something like bellow, but can't get it right:


FillData(new QString[2]() << setting1 << setting2);

PS: I know I can uset QStringList, but just curious, thanks.

Radek
21st August 2015, 07:54
This won't pass. But it will pass if line (and the argument of FillData()) is a QStringList. In the later case:


FillData(new QStringList() << setting1 << setting2);

See QStringList documentation. Also decide, what you will do with the allocated anonymous QStringList passed to FillData(). It needs to be deleted in the end and the FillData() should be a bit secure and foolproof.

arcull
21st August 2015, 08:28
This won't pass. But it will pass if line (and the argument of FillData()) is a QStringList. In the later case:


FillData(new QStringList() << setting1 << setting2);

See QStringList documentation. Also decide, what you will do with the allocated anonymous QStringList passed to FillData(). It needs to be deleted in the end and the FillData() should be a bit secure and foolproof.
Thanks Radek. So if the parameter FillData is just not QStringList I can't use this type of syntax? Definition of FillData is like


void MainWindow::FillData(QString settingLine[]) {
//some code
}

Radek
21st August 2015, 09:20
You cannot because the operation << isn't defined for pointers to a QString (and an array of QStrings is, in fact, a pointer to a Qstring).

anda_skoa
21st August 2015, 10:20
Definition of FillData is like


void MainWindow::FillData(QString settingLine[]) {
//some code
}

That signature is missing the length argument, i.e. how long the array is.
One of the advantages of using a container is that this bit of information is always accessible because it is something the container instance knowns.

Cheers,
_

arcull
21st August 2015, 10:34
That signature is missing the length argument, i.e. how long the array is.
One of the advantages of using a container is that this bit of information is always accessible because it is something the container instance knowns. It's true, but it works, since I know the number of elements in array is fixed. However the answer to the original question is still a bit foggy... If I don't use QstringList, can I use syntax similar to suggested firstplace?

ars
22nd August 2015, 15:38
Hello,

did you consider using some c++11 features? You could rewrite your code using something like


void FillData(const QVector<QString>& strings)
{
for(const auto& string : strings)
{
std::cout << string.toStdString() << std::endl;
}
}

...

FillData({"string1", "string2", "string3"});


or better using an initializer list:


void FillData1(std::initializer_list<QString> strings)
{
for(const auto& string : strings)
{
std::cout << string.toStdString() << std::endl;
}
}

...

QString setting1 = "string1";
QString setting2 = "string2";
QString setting3 = "string3";
FillData1({setting1, setting2, setting3});


If you want to limit the number of settings to at most 2, you could also use


void FillData2(const std::array<QString,2>& strings)
{
for(const auto& string : strings)
{
std::cout << string.toStdString() << std::endl;
}
}

...

FillData2({setting1});
FillData2({setting1, setting2});
FillData2({setting1, setting2, setting3}); // Error: too many arguments! (only 2 allowed)

To use it with Qt5 add


CONFIG += c++11

to your .pro file.

With c++11 initializer lists supported by Qt5 containers I personally prefer using initializer lists instead something like


QStringList() << "string1" << "string2" << ...;


Best regards
ars

arcull
24th August 2015, 06:45
ars, thanks for nice code snippets :)

wysota
24th August 2015, 14:06
It's true, but it works, since I know the number of elements in array is fixed. However the answer to the original question is still a bit foggy... If I don't use QstringList, can I use syntax similar to suggested firstplace?

Passing a bare C array of QString instances is a very questionable approach as far as c++ is concerned. There is no practical reason to be doing that.

arcull
25th August 2015, 13:05
Passing a bare C array of QString instances is a very questionable approach as far as c++ is concerned. There is no practical reason to be doing that. Ok so the definition like following woud be ok?

void MainWindow::FillData(QString settingLine[2]) {
//some code
}

Radek
25th August 2015, 15:19
void MainWindow::FillData( QStringList& settingLine )
{
code
}

or const QStrinList& settingLine if settingLine won't be modified.

arcull
26th August 2015, 07:06
void MainWindow::FillData( QStringList& settingLine )
{
//code
}

or const QStrinList& settingLine if settingLine won't be modified.
Is the apersend sign ("&") a must? I will be calling function passing parameters "by value", but I can add a const qualifier. So it would look like this:


void MainWindow::FillData(const QStringList settingLine )
{
code
}

QStringList list;
list << "A" << "B";
FillData(list);
How does it look ;)

Radek
26th August 2015, 08:25
No, it is not. It only saves stack and time. If you call "by value", the settinLine will be copied on the stack and deleted from the stack on return. If you call "by reference" (the ampersand), the pointer to an existing object will be placed on the stack. You need to delete the referenced object yourself.

wysota
26th August 2015, 08:44
Is the apersend sign ("&") a must? I will be calling function passing parameters "by value", but I can add a const qualifier. So it would look like this:


void MainWindow::FillData(const QStringList settingLine )
{
code
}

QStringList list;
list << "A" << "B";
FillData(list);
How does it look ;)

Better use "const QStringList& settingLine".

With C++11 you can also use:


FillData({"A", "B"});
which should construct the string list on the fly. This is the shortest code you can write to make it work.

arcull
26th August 2015, 09:03
No, it is not. It only saves stack and time. If you call "by value", the settinLine will be copied on the stack and deleted from the stack on return. If you call "by reference" (the ampersand), the pointer to an existing object will be placed on the stack. You need to delete the referenced object yourself.
That is what I want, I mean call "by value", thanks for making it clear.

Added after 6 minutes:


No, it is not. It only saves stack and time. If you call "by value", the settinLine will be copied on the stack and deleted from the stack on return. If you call "by reference" (the ampersand), the pointer to an existing object will be placed on the stack. You need to delete the referenced object yourself.
That is what I want, I mean call "by value", thanks for making it clear.

Added after 8 minutes:


Better use "const QStringList& settingLine".

With C++11 you can also use:


FillData({"A", "B"});
which should construct the string list on the fly. This is the shortest code you can write to make it work.
Ok thanks for suggestion.