is there a way to clear a structure of vectors at a time using a single statement ?
i.e.
struct AStruct
{
vector StringList;
vector DistanceList;
}A;
i want both the vectors using a single statement.
Sure:
AStruct a;
// stuff
a = AStruct(); // clear it
However, I would probably give myself a function:
struct AStruct {
vector <string> StringList;
vector <string> DistanceList; }
void clear() {
StringList.clear();
DistanceList.clear();
}
};
You can then say:
AStruct a;
// stuff
a.clear(); // clear it
which is perhaps easier to understand.
Related
I am a newbie to C and C++, and am trying to use vectors for a specific problem. I have used the example below and can load the contents of both structures into "both" vectors. However, I need to be able to use "push_back" to load the "assessment" structure values (as well as the "subject" details). Is this possible? Any assistance would be most appreciated:-)
#include <vector>
using namespace std;
struct assessment {
int points;
int total;
};
struct subject {
string name;
int marks;
int credits;
vector<assessment> assessments;
};
int main() {
vector<subject> sub {
{"english", 10, 0, {assessment{1,3,0.33f},
assessment{2,3,0.66f},
assessment{3,3,1.00f}
}
},
{"math" , 20, 5, {assessment{2,4,0.50f}
}
}
};
}
I have tried first loading both structures with "dummy" data, and can add to the "subject" using push_back, but can't figure out the syntax to do the same for "assessments" I was hoping to be able to do something like:-
assessment a;
a.points=20;
a.total=50;
sub.assessments.push_back(a);
The error I get is:- std::vector<subject>' has no member named 'assessments'
I am shifting from Python to C so bit rusty on the semantics as well as coding habit. In Python everything is treated as an object and objects are passed to functions. This is not the case in C so I want to increment an integer using pointers. What is the correct assignment to do so. I want to do it the following way but have the assignments wrong:
#include <stdio.h>
int i = 24;
int increment(*i){
*i++;
return i;
}
int main() {
increment(&i);
printf("i = %d, i);
return 0;
}
I fixed your program:
#include <stdio.h>
int i = 24;
// changed from i to j in order to avoid confusion.
// note you could declare the return type as void instead
int increment(int *j){
(*j)++;
return *j;
}
int main() {
increment(&i);
printf("i = %d", i);
return 0;
}
Your main error was the missing int in the function's argument (also a missing " in the printf).
Also I would prefer using parentheses in expressions as *j++ and specify exactly the precedence like I did in (*j)++, because I want to increment the content of the variable in the 'j' location not to increment the pointer - meaning to point it on the next memory cell - and then use its content.
I want to use something like
typedef double Matrix[4][4];
to represent transformations and also pass them around with the QT signal/slot mechanism. But when I use
Q_DECLARE_METATYPE(Matrix)
it throws an error in qmetatype.h at this function
void *qMetaTypeConstructHelper(const T *t)
{
if (!t)
return new T();
return new T(*static_cast<const T*>(t));
}
saying: "error C2075: 'Target of operator new()' : array initialization needs curly braces"
Q_DECLARE_METATYPE(T) requires the type T to be default-constructable, copiable and destructable. Your Matrix type is not copiable, thus you can't use Q_DECLARE_METATYPE on it.
Workaround: use a class.
// copiable, C++98 brace-initializable, etc.
struct Matrix {
double data[4][4];
};
Ideally you should be using eigen3 and its types. Alternatively, wrap your type in a class. Once you do it, you might as well have the class do more than be a mere wrapper. Eventually, you'll see that eigen3 is the only sane way to proceed. Probably when you get to this point:
#include <cstring>
class Matrix {
double m_data[4][4];
public:
typedef double (*Data)[4];
Matrix() {}
Matrix(const Matrix & other) { memcpy(m_data, other.m_data, sizeof m_data); }
Matrix & operator=(const Matrix & other) { memcpy(m_data, other.m_data, sizeof m_data); return *this; }
Matrix & operator=(const Data other) { memcpy(m_data, other, sizeof m_data); return *this; }
operator Data() { return m_data; }
};
int main()
{
double mat1[4][4];
Matrix mat2;
mat2[3][3] = 1;
mat2 = mat1;
return 0;
}
I have a QList consist of QVector3D. A QVector3D represents a vertex or a point. This List holds also all vertices of a STL-File. The problem is that a vertex exist multiple times in the list. In need a list of the unique vertices of a STL-File. How can i implement it with Qt 5.0.2?
QSet uses a hash-function for ensuring the uniqueness of the value (QMap uses operator <)
There is no qHash implementation for QVector3D in Qt.
You could implement your own one e.g. as in example:
//place anywhere in Qt-code
#include <QSet>
#include <QVector3D>
#include <QList>
uint qHash(const QVector3D &v)
{
return qHash( QString( "%1x%2x%3" ).arg(v.x()).arg(v.y()).arg(v.z()) ) ;
}
int foo()
{
QList<QVector3D> uvector3D_1;
QSet<QVector3D> uvector3D_2;
uvector3D_2 = QSet<QVector3D>::fromList(uvector3D_1);
return 0;
}
static int testFoo = foo();
Of cause it is not the fastest one, it relies on Qt's function qHash for QString. But I think it's good for demonstration.
QList<QVector3D> originalVector = ...;
then either:
QSet<QVector3D> noDublicatesSet = QSet<QVector3D>::fromList(originalVector);
or
QSet<QVector3D> noDublicatesSet = originalVector.toSet();
also you can add something like if you need QList back..
QList<QVector3D> destinationVector = QList<QVector3D>::fromSet(noDublicatesSet);
you also will need those things (sorry has them in my code for ages.. forgot that they are external).. you might want to change hash function:
#define ROTL10(x) (((x) << 10) | (((x) >> 22) & 0x000000ff))
#define ROTL20(x) (((x) << 20) | (((x) >> 12) & 0x0000ffff))
uint qHash(double data)
{
union U {
quint64 n;
double f;
};
U u;
u.f = data;
return u.f;
}
inline uint qHash(const QVector3D &v, uint seed)
{
return qHash(v.x()) ^ ROTL10(qHash(v.y())) ^ ROTL20(qHash(v.z()));
}
P.S. that's a code for Qt 5.0, actually to add missing qHash() for vectors, that's why they dont fit in QSet/QHash by default
Starting from Qt 5.14, you can use the new constructor:
template <typename InputIterator> QSet::QSet(InputIterator first, InputIterator last
Here is an example taken from the docs:
// For example, if you have code like
QStringList list;
QSet<QString> set = QSet<QString>::fromList(list);
// you can rewrite it as
QStringList list;
QSet<QString> set(list.begin(), list.end());
I am sorry that I cannot support my question with some code (I didnt understand how to structure it so it would be accepted here), but I try anyway.
If I understand correctly, a struct that references a struct of same type would need to do this with contained pointer for reference. Can this pointer reference to allocated space on the stack (instead of the heap) without creating segmentation fault? -
how should this be declared?
Yes, you can use pointers to variables on the stack, but only when the method that provides that stack frame has not returned. For example this will work:
typedef struct
{
int a;
float b;
} s;
void printStruct(const s *s)
{
printf("a=%d, b=%f\n", s->a, s->b);
}
void test()
{
s s;
s.a = 12;
s.b = 34.5f;
printStruct(&s);
}
This will cause an error however, as the stack frame would have disappeared:
s *bad()
{
s s;
s.a = 12;
s.b = 34.5f;
return &s;
}
EDIT: Well I say it will cause an error, but while calling that code with:
int main()
{
test();
s *s = bad();
printStruct(s);
return 0;
}
I get a warning during compilation:
s.c:27:5: warning: function returns address of local variable [enabled by default]
and the program appears to work fine:
$ ./s
a=12, b=34.500000
a=12, b=34.500000
But it is, in fact, broken.
You didn't say what language you are working in, so assuming C for now from the wording of your question... the following code is perfectly valid:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t str1;
str_t str2;
str1.pNext = &str2;
In this example both str1 and str2 are on the stack, but this would also work if either or both were on the heap. The only thing you need to be careful of is that stack variables will be zapped when they go out of scope, so if you had dynamically allocated str1 and passed it back out of a function, you would not want str1->pNext to point to something that was on the stack within that function.
In other words, DON'T DO THIS:
typedef struct str_t_tag {
int foo;
int bar;
struct str_t_tag *pNext;
} str_t;
str_t *func(void)
{
str_t *pStr1 = malloc(sizeof(*pStr1));
str_t str2;
pStr1->pNext = &str2;
return pStr1; /* NO!! pStr1->pNext will point to invalid memory after this */
}
Not sure if this is specifically a C/C++ question, but I'll give C/C++ code as example in anyway.
The only way you can declare it: (with minor variations)
typedef struct abc
{
struct abc *other;
} abc;
other can point to an object on the stack as follows:
abc a, b; // stack objects
b.other = &a;
This is not a question about scope, so I'll skip commenting on possible issues with doing the above.
If, however, you want to assign it to a dynamically created object, there's no way this object can be on the stack.
abc b;
b.other = malloc(sizeof(abc)); // on the heap