How to you use operator Int() of QFlags? - qt

Documentation: http://doc.qt.io/qt-5/qflags.html#operator-Int
The question. I want to know what flags are set withouth testing one by one so I want the int number. Can anyone provide an example of how to use that operator in one of the many qt methods that rerturn a QFlags?

By referring to QFlags.h source code (https://android.googlesource.com/platform/prebuilts/android-emulator-build/qt/+/master/common/include/QtCore/qflags.h)
This is the definition in QFlags for "Int" operator.
Q_DECL_CONSTEXPR inline operator Int() const Q_DECL_NOTHROW { return i; }
And the "i" in return statement is declared as
Int i;
And the "Int" is declared as
typedef int Int
Notice the below two constructors of QFlags. The first constructor takes Enum as parameter and the second constructor takes QFlag as parameter.
Q_DECL_CONSTEXPR inline QFlags(Enum f) Q_DECL_NOTHROW : i(Int(f)) {}
Q_DECL_CONSTEXPR inline QFlags(QFlag f) Q_DECL_NOTHROW : i(f) {}
After noticing the above constructors, if Enum is passed to the constructor, the Enum can be a signed one or unsigned one. QFlags internally type casts it to int using Int.
Consider below example now.
//Qt::CursorShape is an Enum
Qt::CursorShape shape = Qt::ArrowCursor;
//Create QFlags object by passing "ENUM" as parameter
QFlags<Qt::CursorShape> qF(shape);
//Create QFlags object by just passing FLAG as a parameter
QFlags<Qt::CursorShape> q(Qt::ArrowCursor);
Now the situation where "Int" operator is called: In the below piece of code the first statement invokes Int operator and not in the second statement.
//Now try getting the values.
int test = qF; //In this case the "Int" operator is called.
int test1 = q;

Related

Initialization of dynamically allocated structures using shared pointer

I dont understand why initialization of dynamically allocated structure needs to be done like this (using shared ptr)
Just to notify that I am using C++11
If we have struct like this
struct Meme {
std::string s;
Meme* p;
}
and later in code, I need to dynamically allocated memory for this structure using shared_ptr, but I need to do instant initialization of structure.
Why it is done like this?
std::shared_ptr<Meme> novi=std::make_shared<Meme>(Meme{imena.at(i),nullptr});
part that confuses me is this one :
std::make_shared<Meme>(Meme{imena.at(i),nullptr});
If we set that shared_ptr points to struct Meme, why we need to specify again that initialization list is for struct Meme, by saying
(Meme{imena.at(i),nullptr})
Why this would not work:
std::shared_ptr<Meme> novi=std::make_shared<Meme>({imena.at(i),nullptr});
Is this maybe that initialization list cannot deduct that it should like convert to struct Meme because there is no direct usage of struct Meme(even though make_shared points to struct Meme) ?
make_shared forwards arguments to constructor.
Make shared_ptr
Allocates and constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr that owns and stores a pointer to it (with a use count of 1).
This calls the copy constructor of Meme from new instance you create with Meme{imena.at(i),nullptr}.
std::shared_ptr<Meme> novi=std::make_shared<Meme>(Meme{imena.at(i),nullptr});
The correct way to construct it with make_shared from forwarded arguments is to create constructor in struct:
struct Meme {
std::string s;
Meme* p;
Meme(const std::string& s, Meme* p) : s(s), p(p) {}
};
std::shared_ptr<Meme> novi = std::make_shared<Meme>(imena.at(i),nullptr);
Also you can create an instance with (default) empty constructor and then set its members:
struct Meme {
std::string s;
Meme* p = nullptr;
};
std::shared_ptr<Meme> novi = std::make_shared<Meme>;
novi->s = imena.at(i);

c - Array of pointer to functions, having different number of arguments

I am making a simple scheduler that executes functions contained in a FIFO queue.
Those functions have a same return type int, but have different number of int arguments.
I tried to implement it this way, but it does not seem to work. The compiler forbids conversion between int(*)() , int(*)(int), int(*)(int, int), or to any of those sort. (Arduino Sketch compiler)
Is there a way to solve this problem, or could you recommend a better way around? Thanks!
My code:
typedef int (*fnptr)(); // Tried this!
int foo(int var) {
return 0;
}
int main() {
fnptr fp = &foo; // error: invalid conversion from
// 'int (*)(int)' to 'int (*)()'
// [-fpermissive]
return 0;
}
You can cast:
fnptr fp = reinterpret_cast<fnptr>(foo);
The ()s are the "function call operator", adding them makes no sense at all in this situation, it changes the expression from "take the address of this function" to "take the address of this function's return value".
Note that aboev I don't even include the &, this is because the name of a function acts pretty much like a function pointer so it's already an address.

Error: forming pointer to reference type 'const std::pair<double, unsigned int>&'.... I can't understand this error

I'm getting some errors when trying to use -> in an iterator type. When I dig in the library defining the iterator, it seems to me that everyhing is allright and that there is no reason for the error. Here is the code, part of boost::multi_array:
template <class T>
struct operator_arrow_proxy
{
operator_arrow_proxy(T const& px) : value_(px) {}
T* operator->() const { return &value_; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
operator T*() const { return &value_; }
mutable T value_;
};
which is instantiated with const std::pair<double, unsigned int>&; then the compiler complains about "forming pointer to reference type 'const std::pair<double, unsigned int>&'".Those are internal, library substantiations. For the record, here is what I have in my code:
typedef uint32_t object_indentifier_t;
typedef std::pair< double, object_identifier_t > object_tab_t;
typedef boost::multi_array< object_tab_t, 2 > index_t;
and here is the usage that provokes the trouble:
object_identifier const& center; // Actually a parameter
index_t::const_subarray<1>::type::const_iterator pos_iterator_left = std::lower_bound( ix[i].begin(), ix[i].end(), sk[i], comparer );
assert( pos_iterator_left -> second == center ); // <-- Error steams from here
Here's more error context:
/opt/boost_1_48_0/include/boost/multi_array/iterator.hpp: In instantiation of 'struct boost::detail::multi_array::operator_arrow_proxy<const std::pair<double, unsigned int>&>':
csrc/lsh_cpp/lsh.cpp|125 col 13| required from here
/opt/boost_1_48_0/include/boost/multi_array/iterator.hpp|40 col 10| error: forming pointer to reference type 'const std::pair<double, unsigned int>&'
/opt/boost_1_48_0/include/boost/multi_array/iterator.hpp|43 col 7| error: forming pointer to reference type 'const std::pair<double, unsigned int>&'
csrc/lsh_cpp/lsh.cpp: In member function 'lsh_cpp::neighbour_iterator_t lsh_cpp::lsh_t::pimpl_t::query(const object_identifier_t&) const':
csrc/lsh_cpp/lsh.cpp|125 col 13| error: result of 'operator->()' yields non-pointer result
NOTE: This class is part of boost::multi_array, (I already wrote that), and I'm not instantiating it directly. I wrote above my instantiation. The class is instantiated by boost::multi_array this way:
operator_arrow_proxy<reference>
operator->() const
{
return operator_arrow_proxy<reference>(this->dereference());
}
The use of "reference" makes me think that the reference is intended. Is there a reason for taking address to a reference to not work? I think to remember having done it myself a couple of times, and getting the address of the original, aliased variable that way....
Taking address of a reference is not a problem, but it returns pointer to the underlying type, not pointer to reference. Pointers to reference can't be created nor would they make sense since references cannot be rebound. Declaring a pointer to reference type is an error.
The return type T * therefore won't work if T is a reference type. Similarly declaring a mutable T makes no sense if T is a reference type, because references cannot be rebound. So the operator_arrow_proxy is apparently written to expect a non-reference.
If boost instantiates it with reference member of anything, which is always a reference type, it looks like a bug. Indeed, appears to be reported as bug #6554.

foreach not working on list of QPair

Using Qt, I want this code to work:
QList<QPair<QString, QString>> list;
foreach (QPair<QString, QString> pair, list)
{
}
instead, I get the error:
'pair' : undeclared identifier
Using a typedef I can make it work, but this is not what I want (unless this is the only thing that works):
typedef QPair<QString, QString> MyPair;
QList<MyPair> list;
foreach (MyPair pair, list)
{
}
Can anyone explain why the first foreach doesn't compile?
it's not the foreach error. It's declaration error. You declared list like this:
QList<QPair<QString, QString>> list;
while it should this way:
QList<QPair<QString, QString> > list;
Just declare QPair outside of loop:
QPair<QString,QString> pair;
foreach(pair,list){
}
It is not possible to use template classes inside qt foreach statement which contains more than one template parameter, because comma separator conflicts with comma separator inside macros.
#define add( a, b ) (a + b)
template < typename T1, typename T2 >
struct DATA
{
static const T1 val1 = 1;
static const T2 val2 = 2;
};
// Usage
const int c = add( 1, 2 ); // OK
const int d = add( DATA< int, int >::val1 , DATA< int, int >::val2 ); // FAIL
because macros add will interpret "DATA< int" as first argument, and " int >::val1" as second, and so on.
Some explanation with above answer... if your compiler accept
QList<QPair<QString, QString>> list;
giving no error on such declaration, reasons for topic caster error is different and indeed has to do with a fact that declaration must be done outside of foreach() loop. That's explained in QT documentation.
regarding >> and > >... that's old story and latest GCC (so linux/mac) consider it to be a syntax mistake, because it's not conforming standard. >> in GCC manner is treated as operator with all follow-up errors..

Pointer won't return with assigned address

I'm using Qt Creator 4.5 with GCC 4.3 and I'm having the following problem that I am not sure is Qt or C++ related: I call a function with a char * as an input parameter. Inside that function I make a dynamic allocation and I assign the address to the char *. The problem is when the function returns it does not point to this address anymore.
bool FPSengine::putData (char CommandByte , int Index)
{
char *msgByte;
structSize=putDatagrams(CommandByte, Index, msgByte);
}
int FPSengine::putDatagrams (char CommandByte, int Index, char *msgByte)
{
int theSize;
switch ( CommandByte ) {
case (CHANGE_CONFIGURATION): {
theSize=sizeof(MsnConfigType);
msgByte=new char[theSize];
union MConfigUnion {
char cByte[sizeof(MsnConfigType)];
MsnConfigType m;
};
MConfigUnion * msnConfig=(MConfigUnion*)msgByte;
...Do some assignments. I verify and everything is OK.
}
}
return theSize;
}
When I return the pointer it contains a completely different address than the one assigned in putDatagrams(). Why?
...
Ok thx I understand my mistake(rookie mistake :( ). When sending a pointer as an input parameter to the function you send the address of your data but not the address of your pointer so you cant make the pointer point somewhere else...it is actually a local copy like Index. The only case the data would of been returned succesfully with the use of a char * is by allocating the memory before the function call:
bool FPSengine::putData (char CommandByte , int Index)
{
char *msgByte;
msgByte=new char[sizeof(MsnConfigType)];
structSize=putDatagrams(CommandByte, Index, msgByte);
}
int FPSengine::putDatagrams (char CommandByte, int Index, char *msgByte)
{
int theSize;
switch ( CommandByte ) {
case (CHANGE_CONFIGURATION): {
theSize=sizeof(MsnConfigType);
union MConfigUnion {
char cByte[sizeof(MsnConfigType)];
MsnConfigType m;
};
MConfigUnion * msnConfig=(MConfigUnion*)msgByte;
...Do some assignments. I verify and everything is OK.
}
}
return theSize;
}
There are two ways. The pass-by-value way (C style):
int FPSengine::putDatagrams (char CommandByte, int Index, char **msgByte)
Note the second * for msgByte. Then inside of putDatagrams(), do:
*msgByte = new char[theSize];
In fact, anywhere in that function where you currently have msgByte, use *msgByte. When calling putDatagrams(), do:
structSize=putDatagrams(CommandByte, Index, &msgByte);
And the second way, since you're in C++, you could use pass-by-reference. Just change the signature of putDatagrams() to:
int FPSengine::putDatagrams (char CommandByte, int Index, char * &msgByte)
And you should be good. In this case, you shouldn't need to modify the caller or anything inside of your putDatagrams() routine.
Well, yes. Everything in C++ is, by default, passed by value. Parameters in the call putDatagrams(a, b, c) are sent by value - you wouldn't expect assigning to index in the code to change the value of b at the call site. Your msgByte=new char[theSize]; is just assigning to the local variable msgByte, overwriting the value passed in.
If you want to change a passed parameter such that the call site variable changes, you'll need to either pass by reference, or (in this case) pass a "pointer to a pointer` (and deference away the first pointer, assigning to the actual pointer).

Resources