How to retrieve QPair from QVariant? - qt

I'm doing auto data = combobox->currentData().value<QPair>(); but the compiler complains with:
[ 48%] Building CXX object src/CMakeFiles/mudlet.dir/dlgProfilePreferences.cpp.o
/home/vadi/Programs/Mudlet/mudlet/src/dlgProfilePreferences.cpp: In lambda function:
/home/vadi/Programs/Mudlet/mudlet/src/dlgProfilePreferences.cpp:420:81: error: no matching function for call to ‘QVariant::value()’
auto data = script_preview_combobox->currentData().value<QPair>();
^
In file included from /home/vadi/Programs/Qt/5.9/gcc_64/include/QtCore/QVariant:1:0,
from /home/vadi/Programs/Mudlet/mudlet/cmake-build-debug/src/ui_profile_preferences.h:12,
from /home/vadi/Programs/Mudlet/mudlet/src/dlgProfilePreferences.h:27,
from /home/vadi/Programs/Mudlet/mudlet/src/dlgProfilePreferences.cpp:25:
/home/vadi/Programs/Qt/5.9/gcc_64/include/QtCore/qvariant.h:351:14: note: candidate: template<class T> T QVariant::value() const
inline T value() const
^
/home/vadi/Programs/Qt/5.9/gcc_64/include/QtCore/qvariant.h:351:14: note: template argument deduction/substitution failed:
src/CMakeFiles/mudlet.dir/build.make:806: recipe for target 'src/CMakeFiles/mudlet.dir/dlgProfilePreferences.cpp.o' failed
As far as I see, my call is lining up with template<class T> T QVariant::value() - what's wrong?

QPair is a template class and your code for getting the value from the variant does not fully describe the type.
First you need to know what two types your QPair describes. Then you must use the following code to extract it (changing the QString and int to your pairs data types):
auto pair = combobox->currentData().value<QPair<QString, int> >();

Related

Why does a module type annotation in OCaml cause this code to not compile?

I am working with the Map module in OCaml. Consider the following code to create a map with ints as keys:
module Int = struct
type t = int
let compare a b = a - b
end
module IntMap = Map.Make(Int)
let m = IntMap.(empty |> add 3 "hello")
This all works fine. It compiles and behaves as I would expect.
However, if I add a type annotation for the Int module so the top line becomes:
module Int : Map.OrderedType = struct
The final line causes an error in compilation:
let m = IntMap.(empty |> add 3 "hello")
^
Error: This expression has type int but an expression was expected of type
IntMap.key = Int.t
However IntMap.key and Int.t are both just an alias for int. Furthermore the Int module is of type Map.OrderedType. I know this because that's the required type for Map.Make.
So what an earth is going on here? Why would providing a type annotation that isn't necessary cause an error like this. Do type annotations cause stricter accessibility and not behave the same as inferred types?
This kind of annotation strictly limits the interface of a module. So it seems to me that with the added annotation the only things known about the key type of the map are as given by Map.OrderedType:
module type OrderedType =
sig type t val compare : t -> t -> int end
This says nothing about the type t except that it exists and that it appears in the parameters of compare. In other words, you have hidden the fact that the type t (also known as IntMap.key) is the same type as int.
You can re-introduce this fact using with:
module Int : Map.OrderedType with type t = int = struct
type t = int
let compare a b = a - b
end

Vector of registers size can not be parametrized by module parameter

I want to use module parameter as a size parameter of Vector, which contains registers, and I try next code:
package Test;
import Vector :: *;
(* synthesize *)
module mkTest #(
parameter UInt#(32) qsize
) (Empty);
Vector#(qsize,Reg#(Bit#(8))) queue <- replicateM (mkReg (0));
endmodule
endpackage
But compiling this module with bsc I get next error message:
Verilog generation
bsc -verilog -remove-dollar Test.bsv
Error: "Test.bsv", line 9, column 11: (T0008)
Unbound type variable `qsize'
bsc version:
Bluespec Compiler (build e55aa23)
If I use not Registers as a type of Vector elements, everything is OK. Next code will produce no errors:
package Test;
import Vector :: *;
(* synthesize *)
module mkTest #(
parameter UInt#(32) qsize
) (Empty);
Vector#(qsize,Bit#(8)) queue = replicate(0);
endmodule
endpackage
And I can not understand, why qsize is Unbound as it is clearly declared as a parameter? If I did something wrong, could you please help me and explain, how to make parameterized size Vector of Regs correctly?
I have asked this question in one of the Bluespec repositories on github and Rishiyur S. Nikhil gave me a very full explanation. See https://github.com/BSVLang/Main/issues/4
In short: Vector as a first parameter needs a type, not UInt (or Int or something else). So the right way to do will be:
Make an interface for module and make it type-polymorphic
Use type from that interface as a Vector size parameter
package Test;
import Vector :: *;
interface Queue_IFC #(numeric type qsize_t);
method Bool done;
endinterface
module mkQueue ( Queue_IFC #(qsize_t) );
Vector #(qsize_t, Reg #(Bit #(8))) queue <- replicateM (mkReg (0));
endmodule
endpackage

Argument attribute definition for Qore function implemented via QPP

I'd like to define a CPP __attribute__ for (Qore script) functions implemented in .qpp and preprocessed into plain .cpp.
Qore script class methods may be called from C++ side. In this case an empty function is implemented in QPP class definition and preprocessed in .cpp file. C++ compiler will raise warning messages during compilation. Solution is GNU attribute unused. Is somehow possible to define argument attributes in .qpp ?
MyClass::onAction(int arg0, reference arg1) {
}
Expanded in cpp as:
static QoreValue MyClass_onAction_HashBGD(QoreObject* self, MyClassObject *o, const QoreValueList* args, q_rt_flags_t rtflags, ExceptionSink* xsink)
Note: ScopeGuard.h contains #define UNUSED_VARIABLE __attribute__((unused)) but qpp syntax does not support "normal" C++ usage as argument prefix.
As there are also automatically expanded arguments seems function flag is to be implemented.
I believe this is already implemented; look at the implementation for [doc] in qpp.cpp; if you declare a parameter variable in a qpp file as [doc], it means that no C++ glue for that variable will be generated, and the parameter variable is for documentation only.
Example in QC_StreamWriter.qpp:
nothing StreamWriter::printf(string[doc] fmt, ...) {
sw->f_printf(args, xsink);
}
This generates the following C++ code:
// nothing StreamWriter::printf(string fmt, ...){}
static QoreValue StreamWriter_printf_VsVV(QoreObject* self, StreamWriter* sw, const QoreValueList* args, q_rt_flags_t rtflags, ExceptionSink* xsink) {
# 146 "QC_StreamWriter.qpp"
sw->printf(args, xsink);
return QoreValue();
}
I hope this helps!

'begin' was not declared in this scope

I have a class like that (I leave only the relevant part):
template<class T>
class MyList
{
public:
// ....
typename QList<T*>::iterator begin()
{
return list.begin();
}
typename QList<T*>::iterator end()
{
return list.end();
}
typename QList<T*>::iterator skip(int n)
{
auto ite = list.begin();
while(n --> 0)
++ite;
return ite;
}
QList<T*> list;
};
when I went to use the class:
MyList<Foo*> foo;
for(Foo* f : foo.skip(1)) {
I get this error:
'begin' was not declared in this scope
I remove skip() call, the loop works fine... I don't understand why. Why that and how do I fix this?
This is just how range-based for loops work in C++. In particular, when in a range expression the participant is a class type, in your case MyList, for the expression to be legitimate the class type must have defined members begin and end.
Member function MyList::skip returns an iterator to a QList<T*>. This iterator class doesn't define any begin and end members and the compiler renders this type (i.e., the iterator) not a legitimate participant for a range-based for loop expression while the class type MyList that has defined members begin and end renders legitimate.
More info on how a range-for loop works you can find here.

qRegisterMetaType usage

#include<QMetaType>
typedef QList<int> IntList;
qRegisterMetaType<IntList>("IntList");
error C2909: 'qRegisterMetaType': explicit instantiation of function template requires return type
C2909 says I need to define
template int qRegisterMetaType<IntList>("IntList");
If I define like I mentioned above then I get the below error
error C2059: syntax error : 'string'
warning C4667: 'int qRegisterMetaType(void)' : no function template defined that matches forced instantiation
why do I get this error ?
"qRegisterMetaType" is a function. It must appear in a code block.
int metatype_id = qRegisterMetaType<IntList>("IntList");
You need to add Q_DECLARE_METATYPE(IntList) before you can register it.

Resources