My project is to create a small program which demonstrates the work of a search engine: indexing and returning result for arbitrary queries. I've done the work with the indexer part and now I want to improve it with indexing multiple files at once. The MainWindow class is here:
class MainWindow : public QMainWindow
{
Q_OBJECT
.....
private:
Indexer * indexer;
QStringList fileList;
....
void index(QStringList list);
void add(const QString &filename);
}
This is the implementation of add (add need to access fileList to avoid index the same files again, thus it can not be static method):
void MainWindow::add(const QString &filename)
{
if (!fileList.contains(filename))
{
indexer->addDocument(filename.toStdString());
fileList.append(filename);
qDebug() << "Indexed" << filename;
emit updatedList(fileList);
}
}
The implement of index method is to receive a file lists and call add upon each file name:
void MainWindow::index(QStringList list)
{
....
QtConcurrent::map(list, &MainWindow::add);
....
}
The error I receive when compiling these code is:
usr/include/qt4/QtCore/qtconcurrentmapkernel.h: In member function 'bool QtConcurrent::MapKernel<Iterator, MapFunctor>::runIteration(Iterator, int, void*) [with Iterator = QList<QString>::iterator, MapFunctor = QtConcurrent::MemberFunctionWrapper1<void, MainWindow, const QString&>]':
../search-engine/mainwindow.cpp:361:1: instantiated from here
/usr/include/qt4/QtCore/qtconcurrentmapkernel.h:73:9: error: no match for call to '(QtConcurrent::MemberFunctionWrapper1<void, MainWindow, const QString&>) (QString&)'
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:128:7: note: candidate is:
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:138:14: note: T QtConcurrent::MemberFunctionWrapper1<T, C, U>::operator()(C&, U) [with T = void, C = MainWindow, U = const QString&]
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:138:14: note: candidate expects 2 arguments, 1 provided
I'm not really familiar with how QtConcurrent works, and the documentation doesn't provide much details about it. I really hope that someone here can help. Thanks in advance.
To be able to call a pointer-to-member, you need, in addition to that functions formal arguments, an instance of that class (the this pointer that you get inside member functions).
There are two ways to handle this: create a simple functor to wrap the call, or use a lambda.
The functor would look like this:
struct AddWrapper {
MainWindow *instance;
AddWrapper(MainWindow *w): instance(w) {}
void operator()(QString const& data) {
instance->add(data);
}
};
And you'd use it like:
AddWrapper wrap(this);
QtConcurrent::map(list, wrap);
(Careful with the lifetime of that wrapper though. You could make that more generic - you could also store a pointer-to-member in the wrapper for instance, and/or make it a template if you want to reuse that structure for other types.)
If you have a C++11 compiler with lambdas, you can avoid all that boilerpalte:
QtConcurrent::map(list, [this] (QString const& data) { add(data); });
Note: I'm not sure how QtConcurrent::MemberFunctionWrapper1 got involved in your example, I'm not seeing it here. So there might be a generic wrapper already in Qt for this situation, but I'm not aware of it.
Related
I'm aware of #ClosureParams annotation. It seems to be covering more complex use cases only though. I'm looking for something like described here at the annotating closures section. Which is similar to the following snippet:
void doSomething(MyType src, #ClosureParams(MyType) Closure cl) { ... }
This example no longer compiles with more recent groovy versions unfortunately (I'm on 2.5.8 at the moment). I know I can achieve equivalent with:
void doSomething(MyType src, #ClosureParams(FirstParam) Closure cl) { ... }
My use case doesn't have any other argument than closure itself though:
void doSomething(#ClosureParams(/* how? */) Closure cl) { ... }
I can hack it like:
void doSomething(#ClosureParams(SecondParam) Closure cl, MyType ignore = null) { ... }
It's far from clean, is it not?
I can as well go:
void doSomething(#ClosureParams(value = SimpleType, options = ['com.somepackage.MyType']) Closure cl) { ... }
It's not only ugly and noisy but as well having type specified as string prevents some IDE features from working. For example MyType refactor-rename or search for usages won't be picked up here.
I guess, there isn't any cleaner way of achieving this so type could be specified as a type not a string and without an extra unnecessary argument, is there?
Something like originally posted by Cédric Champeau in the blog post linked above would be ideal. Which in my case would look like:
void doSomething(#ClosureParams(MyType) Closure cl) { ... }
You may want to consider FromAbstractTypeMethods signature hint instead of SimpleType. It is quite verbose to use, but it gives you benefits that are missing from SimpleType hint class - you can easily refactor types defined in the signatures class, as well as you can find usages of classes used in the signature hint. The main downside is that you need to create additional abstract class per closure signature hints, and the name of the class that contains signatures as abstract methods need to be defined as a constant string (the same problem exists with the SimpleType signature hint.) However, you get a single parameter doSomething method, without adding the second null parameter just to be able to use SecondParam signature hint.
package com.example
import groovy.transform.Immutable
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.FromAbstractTypeMethods
class MyClass {
static void doSomething(#ClosureParams(value = FromAbstractTypeMethods, options = ["com.example.MySignatures"]) Closure cl) {
cl.call()
}
static void main(String[] args) {
doSomething {
println it.name
}
}
}
#Immutable
class MyType {
String name
int x
int y
}
abstract class MySignatures {
abstract void firstSignature(MyType myType)
abstract void secondSignature(MyType myType, String str)
}
I guess the simple and clean #ClosureParams(String) variant was removed to satisfy other more complex use cases. The API of ClosureParams annotation is fixed and it limits options to array of strings. Maybe it could be achieved by implementing own ClosureSignatureHint - I have tried that several months ago, but I couldn't make IntelliJ IDEA to use my custom class to provide signature hints.
I found an interesting thing, but I couldn't do it. Is there any way to make the local extension method available in a function with receiver.
val list = ArrayList<Any>();
fun <T> Array<T>.bind(context: MutableList<in T>, block: Array<T>.() -> Unit) {
fun Array<T>.save() {
context.addAll(this);
}
block();
}
arrayOf(1, 2, 3).bind(list) {
save(); //todo: how to bind extension in execution scope
};
I know there is an alternative way by introducing another type for the receiver, but I want to avoid it. for example:
interface Savable {
fun save();
}
fun <T> Array<T>.bind(context: MutableList<in T>, block: Savable.() -> Unit) {
val proxy = object : Savable {
override fun save() {
context += this#bind;
}
};
proxy.block();
}
There is no such feature yet, and I think in near future it won't be added either. You should just use your second version. Don't care about adding an wrapper class. The idea of avoiding introducing a wrapper class is actually, as long as you are using JVM backend, just nonsense, because by using local function you are actually adding a local class.
This is the equivalent Java code of your kotlin function, after fixing as you have suggested, with the assumption that your bind function lives in file bind.kt:
public final class BindKt {
public static <T> void bind(T[] receiver, List<? super T> context, Function1<T> block) {
class Local { // the name of local class is unimportant, as it's generated by compiler. It should looks like "package.name.BindKt$bind$X" where X is a number.
public void save(T[] receiver) {
context.addAll(receiver);
}
}
block.invoke(this); // this won't compile. Neither will yours.
}
}
As you can see save is NOT compiled to a static method, which means, if your block somehow ever called that save, an instance of Local must be fist created. So, no matter what you do, as long as you used a local function, there is basically no point in avoiding introduing a wrapper class. Your second solution is good, and just use it. It's both elegant and efficient enough.
If you really don't want add a class/object creation, move these extension functions to a package scope, and let clients import them.
I am trying to use a simple thread pool example from the book of Anthony Williams "C++ Concurrency in Action". I have even found the code here (the class thread_pool) in one of the posts:
Synchronizing tasks
but I have a different question. I would like to submit a task (a member function) to the queue with the following signature:
class A;
class B;
bool MyClass::Func(A*, B*);
How would I need to change the thread_pool class, or how do I pack my function in some void F(), which is assumed to be used as a task in this example?
Here is the most relevant part of the class for me (for the details please see the link above):
class thread_pool
{
thread_safe_queue<std::function<void()> work_queue; // bool MyClass::Func(a,b) ??
void worker_thread() {
while(!done) {
std::function<void()> task;
if(work_queue.try_pop(task)) {
task(); // how should my function MyClass::Func(a,b) be called here?
}
else {
std::this_thread::yield();
}
}
}
// -- Submit a task to the thread pool
template <typename FunctionType>
void submit(FunctionType f) {
work_queue.push(std::function<void()>(f)); // how should bool MyClassFunc(A*, B*) be submitted here
}
}
And finally, how can I call the submit Function in my code?
Thank you very much for your help (unfortunatelly I am not very experienced yet in using all the C++11 features, which is probably also why I need help here, but an answer to this question would be something to start with :)).
You have to bind the parameters to a value when you insert a task into the queue. That means that you have to create a wrapper for your function that stores the values for this and the values for the two function parameters. There are many ways to do this, e.g. lambda functions or std::bind.
work_queue.push_back( [obj, a, b]() {obj->Func(a,b)} );
work_queue.push_back( std::bind(&MyClass::Func, obj, a, b) );
Your submit function must take these parameters and create the binding, e.g.
template<typename F, typename... Args>
void submit(F f, Args&&... args) {
work_queue.push_back( std::bind(f, std::forward<Args>(args)...) );
}
It may be convenient to create a special overload for member functions and objects.
I've written something that does something (very) similar to this before. I'll post the code here and you can have a look. GenCmd is the function wrapper. The queue looks like this, and is used/defined in Impl (code omitted). You only need to look at implementation of GenCmd, as this contains the necessary work.
ConcurrentQueue<std::unique_ptr<Cmd>> cqueue_;
I've wrapped std::function<> to be polymorphic in queue. std_utility contains make_index_sequence, that is used to extract values from a tuple (google make_index_sequence to find an implementation somewhere if this is not already part of your std library).
#include <functional>
#include <memory>
#include <iostream>
#include <utility>
#include <boost/noncopyable.hpp>
class CmdExecutor : public boost::noncopyable
{
public:
CmdExecutor(std::ostream& errorOutputStream);
~CmdExecutor();
template <class Receiver, class ... FArgs, class ... CArgs >
void process(Receiver& receiver, void (Receiver::*f)(FArgs...), CArgs&&... args)
{
process(std::unique_ptr<Cmd>(new GenCmd<void(Receiver,FArgs...)>(f, receiver, std::forward<CArgs>(args)...)));
}
private:
class Cmd
{
public:
virtual void execute() = 0;
virtual ~Cmd(){}
};
template <class T> class GenCmd;
template <class Receiver, class ... Args>
class GenCmd<void(Receiver, Args...)> : public Cmd
{
public:
template <class FuncT, class ... CArgs>
GenCmd(FuncT&& f, Receiver& receiver, CArgs&&... args)
: call_(std::move(f)),
receiver_(receiver),
args_(args...)
{
}
//We must convert references to values...
virtual void execute()
{
executeImpl(std::make_index_sequence<sizeof...(Args)>{});
}
private:
template <std::size_t ... Is>
void executeImpl(std::index_sequence<Is...>)
{
// We cast the values in the tuple to the original type (of Args...)
call_(receiver_, static_cast<Args>(std::get<Is>(args_))...);
}
std::function<void(Receiver&, Args...)> call_;
Receiver& receiver_;
// NOTE:
// References converted to values for safety sake, as they are likely
// to not be around when this is executed in other context.
std::tuple<typename std::remove_reference<Args>::type...> args_;
};
void process(std::unique_ptr<Cmd> command);
class Impl;
Impl* pimpl_;
};
It's basically used as follows:
...
CmdExecutor context_;
...
void MyClass::myFunction()
{
ArgX x;
ArgY y;
context_.process(*this, &MyClass::someFunction, x, y);
}
You can see from this that process does the wrapping of member function type and converts it to the underlying type for storage on queue. This allows for multiple argument types. I've opted for using runtime polymorphism to store the function types, hence the GenCmd derivative.
Note: If the invoked function receives an rvalue (Arg&&), the stored type is casted to the original type, therefore causing a move, and rendering the applicable command argument (which would only be invoked once) empty (that's the intent, at least - untested...)
I'm trying to create a haxe.ds.HashMap where the keys are an object I don't control. Thus, they don't implement the hashCode method and I can't change them to.
I would really like to use an abstract to accomplish this, but I'm getting some compile time errors.
Here is the code I'm playing with:
import haxe.ds.HashMap;
abstract IntArrayKey( Array<Int> ) from Array<Int> {
inline public function new( i: Array<Int> ) {
this = i;
}
public function hashCode(): Int {
// General warning: Don't copy the following line. Seriously don't.
return this.length;
}
}
class Test {
static function main() {
var hash = new HashMap<IntArrayKey, Bool>();
}
}
The compile errors are:
Test.hx:15: characters 19-51 : Constraint check failure for haxe.ds.HashMap.K
Test.hx:15: characters 19-51 : IntArrayKey should be { hashCode : Void -> Int }
But the moment I change my abstract over to a class, it compiles fine:
import haxe.ds.HashMap;
class IntArrayKey {
private var _i: Array<Int>;
inline public function new( i: Array<Int> ) {
this._i = i;
}
public function hashCode(): Int {
// General warning: Don't copy the following line. Seriously don't.
return this._i.length;
}
}
class Test {
static function main() {
var hash = new HashMap<IntArrayKey, Bool>();
}
}
It's the exact same hashCode implementation, just a different context. Is there some way to accomplish this? Or is it a language limitation?
As far as I know, abstracts currently can't satisfy type requirements like this, quoting from the code:
abstract HashMap<K:{ function hashCode():Int; }, V >(HashMapData<K,V>) {
So, I doubt you could do that in a meaningful way.
Important point would be that while abstracts can sometimes provide overhead-free abstractions which is quite useful for optimizations, the time needed to instantiate(probably hidden from sight with abstract Name(Holder) to Holder having #:from Array<Int> and #:to Array<Int>) holder for your array which will have the required method isn't that high(compared to usual runtime overheads), and unless it is a really frequent code, should be your first way to go.
However, the HashMap code itself is quite short and simple: here.
You could just copy it and make it work with your example. Maybe you could even forge a better yet generic version by using interfaces(though I'm not sure if abstracts can actually implement them).
Suppose I have a List<IMyInterface>...
I have three classes which implement IMyInterface: MyClass1, MyClass2, and MyClass3
I have a readonly Dictionary:
private static readonly Dictionary<Type, Type> DeclarationTypes = new Dictionary<Type, Type>
{
{ typeof(MyClass1), typeof(FunnyClass1) },
{ typeof(MyClass2), typeof(FunnyClass2) },
{ typeof(MyClass3), typeof(FunnyClass3) },
};
I have another interface, IFunnyInteface<T> where T : IMyInterface
I have a method:
public static IFunnyInterface<T> ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
if (DeclarationTypes.ContainsKey(node.GetType())) {
IFunnyInterface<T> otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
return otherClassInstance;
}
return null;
}
I'm trying to call the constructor of FunnyClasses and insert as parameter my MyClass object. I don't want to know which object it is: I just want to instantiate some FunnyClass with MyClass as a parameter.
What happens when I call ConvertToFunnyClass, T is of type IMyInterface, and when I try to cast it to FunnyInterface<T>, it says I can't convert FunnyClass1, for instance, to FunnyInterface<IMyInterface>
My current workaround (not a beautiful one), is this:
public static dynamic ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
if (DeclarationTypes.ContainsKey(node.GetType())) {
var otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
return otherClassInstance;
}
return null;
}
And I don't like it because the return type is dynamic, so when I access it from somewhere else, I have no idea what type it is, and I lose intellisense, and stuff. I don't know about any performance implications either.
Any clues?
Thanks in Advance!
Resolution
As I'm using C# 4.0, I could stop casting errors using covariance (output positions only), and so I changed my IFunnyInterface to
IFunnyInteface<out T> where T : IMyInterface
Thank you all for the replies.
Essentially, your problem is that you are trying to convert FunnyInterface<T> to FunnyInterface<IMyInterface>. As has been mentioned several times (one example is here, more information here), this is not valid in most circumstances. Only in .NET 4, when the generic type is an interface or delegate, and the type parameter has been explicitly declared as variant with in or out, can you perform this conversion.
Is FunnyInterface actually an interface?
thecoop answer points you exactly to why you can't do it.
A cleaner solution to the problem (besides using dynamic) would be a base non-Generics Interface:
public interface IFunnyInterfaceBase
{
}
public interface IFunnyInteface<T> : IFunnyInterfaceBase
where T : IMyInterface
{
}
And you need to move methods signature you use in that code from IFunnyInteface to IFunnyInterfaceBase.
This way you would be able to write something like this:
MyClass2 c2 = new MyClass2();
IFunnyInterfaceBase funnyInstance = c2.ConvertToFunnyClass();
The Exception you said you got in your code is not due to the extension method signature itself (the method is fine)..it is originated by the type of your lvalue (the type of the variable you use to store its return value)!
Obviously this solution applies only if you can modify IFunnyInterface source code!