how to append element to a QList in a structure? - qt

I have a struct like this one :
struct Nom {
QString Nom;
....
QList<quint64> indNum;
}
In my .h file. I declare :
QVector *n;
In my .cpp file. I declare :
n = new QVector<Nom>;
I read a file to fill in n.
When I write this :
n->back().indNum.append(i->size()-1);
it works.
When I write that :
n->at(j).indNum.append(i->size()-1);
I have a compilation error:
no matching member funtion for call to 'append'
candidate function not viable: 'this' argument has type 'const
QList', but method is not marked
const void append(const T &t);
I don't understand why it works in the first case and the second.
Could anyone explain and help me solve this ?
Thanks in advance.

QVector::at returns a const reference to the Nom value, so you cannot modify the item returned by n->at(j). To get a non-const reference you can use (*n)[j].
n->back() works because for QVector::back there is a const and a non-const overload.

Related

How to you use operator Int() of QFlags?

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;

shared_ptr not changing object (Visual studio 2012)

I have a really strange problem. I can't modify the object I am pointing to with a shared_ptr.
Example code:
#include<memory>
#include<iostream>
using namespace std;
class foo
{
public:
int asd;
foo(){}
~foo(){}
};
void d(shared_ptr<foo> c)
{
c->asd = 3;
}
void main()
{
foo a;
a.asd = 5;
d(make_shared<foo>(a));
cout<<a.asd; //asd is still 5
}
As far as I know you can access the object pointed to by the shared_ptr by using the "->" operator, so what am I doing wrong here? How can I change the asd variable inside the class via the shared pointer?
// create a temporary object by copying a
// the shared pointer you pass to d function actually points to this temporary object
d(make_shared<foo>(a));
// allocate and store foo object in shared_ptr instead
auto p_a(make_shared<foo>());
p_a->asd = 3;
d(p_a);
... so what am I doing wrong here?
From cppreference on std::make_shared [emphasis mine]:
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
Constructs an object of type T and wraps it in a std::shared_ptr
using args as the parameter list for the constructor of T.
In your case, you supply an instance of foo as argument to std::make_shared, which will be used when constructing a new object of type foo; i.e., making use of the default supplied copy CTOR of foo (foo(const foo&)). This new object will be a temporary and only live for the call to d(...).

How to use QSet as value in QMap?

I'm using Qt and I want to declare following container:
QMap<QUrl , QSet<ClassSharedPtr> > map;
Here ClassSharedPtr is the boost shared ptr of class "Class".
typedef boost::shared_ptr<const Class> ClassPtr;
I'm getting following errors after adding header file #include :
error: no matching function for call to ‘qHash(const boost::shared_ptr<const Class>&)’
QSet's value data type must be an assignable data type. In addition, the type must provide operator==(), and there must also be a qHash() function in the type's namespace that returns a hash value for an argument of the values's type.
So, you should implement qHash() function for boost::shared_ptr<const Class>.
namespace boost {
uint qHash(const boost::shared_ptr<const Class> &key, uint seed = 0)
{
const Class *ptr = key.get();
return uint(ptr) ^ seed;
}
}

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.

C++/CLI How to translate this code ?

I dont know a lot about C++, but I have to make work some C++ code with .NET. I try with DLLImport but I failed. So I try with C++/CLI to make kind of a wrapper.
But I'm not sure to understand everything...
This is the basic C++ H file with the function I want to export (MyFunction)
extern "C"
{
__declspec(dllexport) IplImage* MyFunction(IplImage *src, std::string* name, OneEnumerationType myEnum, bool myBool, float myFloat);
}
This is the Wrapper h code.
#include "MyFunction.h"; // the file containing the h code
#include <string>
namespace MyWrapper{
public ref class MyWrapperClass {
public:
MyWrapper(){};
IplImage^ GetMyFunction(IplImage *src, std::string^ name, OneEnumerationType myEnum, bool myBool, float myFloat);
}
This is the Wrapper cpp code.
#include "MyWrapperCode.h";
namespace MyWrapper{
IplImage^ MyWrapperClass::GetMyFunction(IplImage* src, std:string^ name, OneEnumerationType myEnum, bool myBool, float myFloat){
MyFunction(src, name, myEnum, myBool, myFloat);
}
}
These are my questions :
1) When I'm compiling, the error is "'^ : cannot use this indirection on type IplImage' and same message for type "std::string".
I have followed this logical :
ClasseNative clNat2 = *clNat; --> ClasseManagee clMan2 = *clMan;
ClasseNative &clNat3 = clNat2; --> ClasseManagee %clMan3 = clMan2;
ClasseNative *clNat4 = &clNat2; --> ClasseManagee ^clMan4 = %clMan2;
I have seen, that It was better to use System::String. I try this way but the initial function is using std::string... BTW, why is it better to change ?
2) How do I get the MyFunction IplImage result ? Thru a private member and a get I suppose but I dont know how to initialize it...
3) Tricky question. Is it possible for me to put the CLI obtains IplImage structure (from the OpenCV library) (the result of my function) inside a IplImage .NET structure, when I ll called my wrapper ? Dont know if the question is understandable...
Thanks a lot for your help.
Turning around for 3 days on this problem...
Your wrapper class needs to create a new std::string based on the content of a System::String^ parameter then pass to your native function. Otherwise you need to rewrite the function to take something else as the string input, for example a LPWSTR or LPCSTR.
You can write a ref class to have properties for all data that an IplImage would have, then pass that to your wrapper class. Your wrapper class then create an IplImage object based on the data of the ref class and pass to the native function. Reverse the data copying direction for the return value.
1) just by adding ^ you cannot change a native object to become managed, you have to create wrappers or transfer the data for example:
std::string nativeString = "my string";
String^ managedString = gcnew String(nativeString.c_str());
//now you can return it as
2) create a managed wrapper or use primitive datatype to transfer the data
3) note sure if this will help but look at Emgu.CV
try reading abit more about C++\CLI here are a few nice tutorials:
Quick C++/CLI - Learn C++/CLI in less than 10 minutes
C++/CLI for the C# programmer

Resources