How does Qt bind pointers-to-non-static-member-functions in QtConcurrent? - c++

From the QtConcurrent documentation:
QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split), ',');
...
QList<QByteArray> result = future.result();
The code snippet above appears to be binding a function in a similar way to std::tr1::bind (std::bind for > C++11). That is to say it's taking a non-static member function (QByteArray::split()) and (at some point later) calling it on the specific instance of the object of which it's a member (which we've supplied as bytearray).
How does Qt achieve this? Is it using std::tr1::bind or boost::bind somewhere behind the scenes?
The documentation does also refer to a case where you would use std::tr1 or boost instead, but I don't fully understand what it means by a bound function in that context. Is the situation above in fact different/more specialised/simpler than other situations where you might otherwise use tr1 or boost?
I've tried to make my way through the source but am getting lost very quickly!

I'm going to attempt a self answer, as the existing answers (many thanks to #Mike Brown and #skyhisi) lay the groundwork but don't address this specific case...
From the source:
QtConcurrent::run(...) :
template <typename T, typename Class>
QFuture<T> run(const Class &object, T (Class::*fn)())
{
return (new QT_TYPENAME SelectStoredMemberFunctionCall0<T, Class>::type(fn, object))->start();
}
SelectStoredMemberFunctionCall0:
template <typename T, typename Class>
struct SelectStoredMemberFunctionCall0
{
typedef typename SelectSpecialization<T>::template
Type<StoredMemberFunctionCall0 <T, Class>,
VoidStoredMemberFunctionCall0<T, Class> >::type type;
};
VoidStoredMemberFunctionCall0:
template <typename T, typename Class>
class VoidStoredMemberFunctionCall0 : public RunFunctionTask<T>
{
public:
VoidStoredMemberFunctionCall0(T (Class::*_fn)() , const Class &_object)
: fn(_fn), object(_object){ }
void runFunctor()
{
(object.*fn)();
}
private:
T (Class::*fn)();
Class object;
};
Given the above, I can see that Qt stores a pointer-to-member-function in the normal way, but by dressing it up in templates which would otherwise go unnoticed, the illusion of generic-ness is created.
The type of VoidStoredMemberFunctionCall0::object as well as the signature of VoidStoredMemberFunctionCall0::fn are all specified above in the arguments passed to QtConcurrent::run.
I wasn't aware that this 'implicit' templatization was even possible, to be honest. Would anybody be able to recommend further reading?

The C++ FAQ explains Pointers to member functions very well and explains the pitfalls.
At some point there would be a line similar to:
ret_val = obj_ptr->*func_ptr(param);
But it will be wrapped up in templates to allow passing any object type and parameter type, and there will be the thread dispatching mixed up in there as well.

You're passing a Function Pointer and an Instance of the Class the function was declared on. Invoking it is as simple as dereferencing the function pointer from the object. This StackOverflow Question shows the answer

Related

Using Concepts to create static polymorphic interface

Hello Stackoverflow community,
I've been really confused on the concepts syntax and am having a hard time getting started.
I would like to create a polymorphic interface for two types of operator types: unary and binary and opted to try out the concept feature in c++20.
Not sure if it matters, but I used a CRTP create my unary functor compatible with binary functors, however I would like to get rid of that. Here's what I have so far:
template <typename T>
concept UnaryMatrixOperatable = requires(T _op) {
_op.template operate(std::unique_ptr<Matrix::Representation>{});
{_op.template operate() } -> same_as<std::unique_ptr<Matrix::Representation>>;
};
class ReLU : public UnaryAdapter<ReLU> {
public:
std::unique_ptr<Matrix::Representation> operate(
const std::unique_ptr<Matrix::Representation>& m);
};
static_assert(UnaryMatrixOperatable<ReLU>);
However, I am getting a compilation error, presumably because I am not doing some sort of template specialization for a const matrix & type?
include/m_algorithms.h:122:13: error: static_assert failed
static_assert(UnaryMatrixOperatable<ReLU>);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/m_algorithms.h:122:27: note: because 'Matrix::Operations::Unary::ReLU' does not satisfy 'UnaryMatrixOperatable'
static_assert(UnaryMatrixOperatable<ReLU>);
^
include/m_algorithms.h:53:26: note: because '_op.template operate(std::unique_ptr<Matrix::Representation>{})' would be invalid: 'operate' following the 'template' keyword does not refer to a template
_op.template operate(std::unique_ptr<Matrix::Representation>{});
^
Thanks for all the help in advance, this design in my code has been problematic for over a week so I'm determined to find a clean way to fix it! Thanks.
Concepts are not base classes, and you should not treat concept requirements like base class interfaces. Base classes specify exact function signatures that derived classes must implement.
Concepts specify behavior that must be provided. So you explain what that behavior is.
The behavior you seem to want is that you can pass an rvalue of a unique pointer to an operate member function. So... say that.
template <typename T>
concept UnaryMatrixOperatable = requires(T _op, std::unique_ptr<Matrix::Representation> mtx)
{
_op.operate(std::move(mtx));
};
There's no need for template here because you do not care if operate is a template function. It's not important in the slightest to your code if any particular T happens to implement operate as a template function or not. You're going to call it this way, so the user must specify some function interface that can be called a such.
The same goes for the zero-argument version. Though your interface should probably make it much more clear that you're moving from the unique pointer in question:
template <typename T>
concept UnaryMatrixOperatable = requires(T _op, std::unique_ptr<Matrix::Representation> mtx)
{
_op.operate(std::move(mtx));
{ std::move(_op).operate() } -> std::same_as<decltype(mtx)>;
};
In any case, the other reason you'll get a compile error is that your interface requires two functions: one that gets called with an object and one that does not. Your ReLu class only provides one function that pretends to do both.

c++ template member function that changes parameters depending on template parameter

---Edit for more context---
Lets say I have a class called TempClass. As the name suggests its a template class. It has a bunch of stuff that doesnt really matter to this question, but the interesting stuff is a member function called addTo and a member variable that is a unordered_map object. Lets call it inserted. Everything in inserted was put in there using addTo. What addTo should do is make some object that is then inserted into the collection at the given key. The inserted instance should be created inside of the function rather than passed to it.
addTo(KeyType key, ...) // im looking for what I should put at ...
Basically I am stuck at everything after key. I need a way I can specify the data for the newly created instance without having to worry about the objects lifetime or complicate things with calls to std::make_xxx(shared, unique etc).
Here is how I want it to be called
TempClass<std::string> stringClass();
stringClass.addTo(whereToAddIt, "This was selected because of std::string");
TempClass<Vector3f> vectorClass();
vectorClass.addTo(someOtherLocation, 12.0f,12.0f,3.0f); //adds a vec(12.0f,12.0f,3.0f)
I have seen this done this way and if this is good practice in general id love to implement it this way.
What I have tried:
Passing a pointer to the function
------> Works but is stupid. It required me to pay attention to deleting the object
Passing a temporary object and copying it before inserting
------> Works but I dislike having to copy the object just to delete it. It seems redunant and is not optimal for my specific application.
I have seen this done before, but I cant remember where (trust me I have tried to remember this, since if I could I could just look it up myself). Please explain to me in detail how to do this and how it works.
Please help me figure this out!
You can use overloads, and then enable a certain overload when your templated type is a certain type
#include <type_traits> //for enable_if and is_same
template<typename T>
class MyClass
{
public:
template<typename = std::enable_if<std::is_same_v<T, std::string>>>
void someMember(string param1, int param2);
template<typename = std::enable_if<std::is_same_v<T, Vector3f>>>
void someMember(string param1, int param2, int param3);
};
This will select the first overload is T is std:string, and the second overload if T is a Vector3f.
Edit: Looking at your edited question, a much better approach would be to just pass an instance of T to your addTo function. Like:
void addTo(std::string key, T const& value);
EDIT2: I think I finally know what you actually want. You need to use variadic templates and perfect forwarding. This might seem confusing, so I will give you code:
template<typename KeyType, typename... Args>
void addTo(KeyType key, Args&&... args)
{
//now construct the new element with:
T elem(std::forward<Args>(args)...);
}
You will need to include the utility header. For more information on variadic templates see cppreference
You can use variadic template and perfect forwarding to emplace a k/v pair:
template<class K, class V>
struct foo {
template<class... Args>
void addTo(K k, Args&&... args) {
mp.emplace(
std::piecewise_construct,
std::forward_as_tuple(k),
std::forward_as_tuple(std::forward<Args>(args)...)
);
}
std::unordered_map<K, V> mp;
};

Type erasure and variadic templated member function

The example below is a minimal, maybe not so good example of a well known idiom.
It compiles and it is so ugly in order to be able to maintain it minimal, because the question is not about the idiom itself.
struct Foo {
virtual void fn() = 0;
};
template<class T>
struct Bar: public Foo {
void fn() override {
T{}.fn();
}
};
struct S {
void fn() { }
};
int main() {
Foo *foo = new Bar<S>{};
foo->fn();
}
What I'm struggling with since an hour ago is how to change it (or even, if there exists an alternative idiom) to introduce a variadic template member method.
Obviously, I cannot modify the fn function of the Foo class, because it's a virtual one and virtual specifier doesn't goes along with templates. The same is valid for the fn specification of Bar, because it has to override somehow the one in the base class.
Note.
For I strongly suspect that this question could be one of the greatest XYProblem ever seen, I'd like also to give a brief description of the actual problem.
I have a class that exposes two templated member methods:
the first one accepts a template class T that is not used immediately, instead it should be stored somehow in order to be used later.
the second one accepts a variadic number of arguments (it is actually a variadic templated member function) and those arguments should be perfectly forwarded to a newly created instance of T.
Well, the problem is far more complex, but this is a good approximation of it and should give you an idea of what's the goal.
Edit
I guess that it is somehow similar to higher order functions.
I mean, what would solve the problem is indeed a templated function to which to bind the first argument, but as far as I know this is impossible as well as any other approach I've explored so far.
Any viable solution that expresses the same concept?
What I mentioned in the comments is the following approach:
template<typename T> class Factory {
public:
template<typename ...Args>
auto construct(Args && ...args)
{
return T(std::forward<Args>(args)...);
}
};
So now, your first exposed class method will be something like this:
template<typename T>
auto getFactory() {
return Factory<T>();
}
So:
auto factory=object.getFactory<someClass>();
// Then later:
factory.construct(std::string("Foo"), bar()); // And so on...
Instead of construct() you could use operator() too, so the second part of this becomes, simply:
factory(std::string("Foo"), bar()); // And so on...
As I mentioned, this is not really type erasure. You can't use type erasure here.
Having given this a few minutes' more thought, the reason that type erasure cannot be used here is because a given instance of type erasure must be "self contained", or atomic, and what you need to do is to break atomic type erasure into two parts, or two class methods, in your case.
That won't work. Type erasure, by definition, takes a type and "erases" it. Once your first function type-erases its class method template parameter, what you end up with is an opaque, type-erased object of some kind. What was type-erased is no longer available, to the outside world. But you still haven't type-erased your constructor parameters, which occurs somewhere else.
You can type-erase the template class, and the constructor parameters together. You can't type-erase the template class, and the constructor parameters, separately and then somehow type-erase the result again.
The simple factory-based approach, like the one I've outlined, would be the closest you can get to results that are similar to type erasure, if both halfs of your desired type-erasure appear in the same scope, so you can actually avoid type-erasure, and instead rely on compiler-generated bloat.
I also agree that you cannot do exactly what you want here. I will post what I think the closest option is (at least a close option that is different from SamVarshavchik's answer).
I don't expect this answer to solve your problem exactly, but hopefully it will give you some ideas.
struct Delay // I have no idea what to call this
{
template <class T>
void SetT()
{
function_ = [](boost::any params){return T(params);}
}
template <class ... Args>
boost::any GetT(Args ... args)
{
return function_(std::make_tuple(args...));
}
private:
std::function<boost::any(boost::any)> function_;
};
The obvious limitation of this is that anyone calling GetT will somehow have to know what T was already, though you can query the boost::any object for the type_info of its class if that helps. The other limitation here is that you have to pass in T's that take a boost::any object and know what to do with it. If you cannot have T do that, then you can change SetT (or create a new member function) like this:
template <class F>
SetTFactory(F f)
{
function_ = f;
}
and then use it like:
Delay d;
d.SetTFactory([](boost::any s){return std::string(boost::any_cast<const char*>(s));});
auto s = d.GetT("Message");
assert(s.type() == typeid(std::string));
This of course introduces a whole new set of difficulties to deal with, so I don't know how viable this solution will be for you. I think regardless of anything else, you're going to have to rethink your design quite a bit.

multiple functions with same name but different argument types as template parameter

I'm using xsd to create c++ code from a xml schema file. For a xml type multiple functions are created (for serialization etc).
If the type is called XmlType multiple functions of the following form are created:
XmlType XmlType_(const XmlType& a, const string& b)
string XmlType_(const XmlType& a)
...
This are normal functions and not members of XmlType and they all have the same name.
For XmlType2 the functions would be called XmlType2_.
I would like to write a utility template class for all the different xml types of my xml scheme. The different functions are going to be called insight this class. What I have so far is something like this:
template<typename T>
using TFunc1 = T (*)(const T&, const string&);
template<typename T>
using TFunc2 = string (*)(const T&);
template<typename T, TFunc1<T> func2, TFunc2<T> func2>
class XmlUtil {
...
};
When create an instance of the XmlUtil class if have to do it like this:
XmlUtil<XmlType, XmlType_, XmlType_> util;
This feels a bit redundant and gets worse, when I have to pass more functions as parameters.
I would like to use the util class like this:
XmlUtil<XmlType, XmlType_> util;
or even better like this
XmlUtil<XmlType> util;
The only way I can think of is to somehow use define, but it doesn't feel right.
Is there an other way to do this?
EDIT:
I'm using a define now:
#define TRPL(name) name, name ## _, name ## _
...
XmlUtil<TRPL(XmlType)> util;
I'll edit this, if I find something better (maybe override sets like Yakk suggested in his answer).
This:
XmlUtil<XmlType> util;
is impossible because there is no way to get from XmlType to XmlType_. Their relationship is discarded after the automatic code generator.
However this:
XmlUtil<XmlType_> util;
may be possible. You can deduce the function type of XmlType_ and then use the deduced return type which will be XmlType. I believe there are standard library function for this purpose.
As for the two different overloads, that may be trickier. I do not think that you can pass a function overload set as a template parameter, the resolution is done on the template argument in the context of the template parameter to one function. I don't think there is a way to defer this action without using the preprocessor.
So I would argue that you should use a #define. It is better than nothing.
This looks like a job for override sets.
static struct foo_override_set_type {
template<typename... Args>
auto operator()( Args...&& args ) const
->
decltype( foo( std::forward<Args>(args)... ) )
{ return ( foo( std::forward<Args>(args)... ) ); }
template<typename T>
operator T() { return foo; }
} foo_override_set;
Objects of type foo_override_set_type represent the entire override set of foo. Calling them with operator() does an override set lookup on foo and calls the resulting function. Casting them to a function pointer does the same thing as casting the token foo to a function pointer (or other value).
Your code generation can auto-generate such override set types. It can also make a traits class that maps from your type XmlType to the override set of XmlType_ functions via specialization.
Then, your XmlUtil<XmlType> can access the override set of XmlType_ via that traits class. It first instantiates the override set variable, then invokes () on it.
As an aside, #Xeo has a proposal to make creating such objects as easy as typing []XmlType_ in C++1y or C++1z.
Default template arguments in the class definition?
Like
template<typename T, TFunc1<T> func1 = XmlType_, TFunc2<T> func2 = XmlType_>
class XmlUtil {
// ...
};
You can use a trait class like this
template <typename T>
struct Trait{
typedef T type;
typedef T (*func1)(const T&, const string&);
typedef string (*func2)(const T&);
};
and make the class XmlUtil have one template parameter (let's name it Trait) and use Trait::type, Trait::func1 and Trait::func2. See here for full usage.
In the example, the type of XmlUtil goes like:
XmlUtil<Trait<XmlType> >
I've done it this way since I don't know well your problem. It might be the case that you can just define the Trait class right into XmlUtil and use
XmlUtil<XmlType>
Other variations are possible, it just depend on what you need.
You can read a very brief introduction to trait classes here. If you want to read more about this topic I suggest you Modern C++ (Alexandrescu).
I am not sure I fully understand what you are asking. The common approach for serialization and deserialization would be to create a factory (abstract factory) and resolve the construction of the objects dynamically. Note that this can be improved for complex structures, where the code generator can create member functions to extract the exact type of each one of the members.
But again, I don't fully understand what you are really trying to do... As a recommendation I believe it would help if you provided more of a description of the problem to solve, as the question focuses on how to make your solution work, and that implicitly discards other approaches that might be better designs.

C++ right way of returning a generic collection of type

I'm new to C++, and unfortunately I cannot stop thinking in C# (my former language).
I read some books, forums and the C++ reference website, but I couldn't find an answer to my question, so I thought I might as well try here before giving up and writing something ugly.
Ok, we can start.
I have a class with an abstract method succesorsFunction and I would like it to return a collection of pointers to State. I don't want to force the implementors to a specific container; I rather let them choose (vector, list, etc).
So it looks like this:
class Problem
{
public:
virtual list<const State*>::iterator succesorsFunction(const State &state, list<const State*>::iterator result) const = 0;
};
the problem here is the explicit use of list. How do you do it in C++?
I thought about using templates, but then I encountered two problems:
1) It seems like you cannot do it with abstract methods (or am I wrong?)
2) How do I tell the template it should contain pointers to State?
You can't overload methods based on return types in C++.
Also, "containers" in C++ don't have the same base (like Collection in Java), so you can't return a generic container.
I'm afraid there's no clean way of doing this.
I would just write overloads (by parameter) or different function names.
For your questions:
1) You can. What makes you think you can't?
2) The same way you declared list: list<const State*> - const is optional.
If you really want to enforce STL container usage, try the following:
template <template <typename,
typename = std::allocator<const State *> > class Container>
Container<const State*> successorsFunction(const State &state, const Container<const State*> &c) const
{
// return something useful.
}
If you insist on having this function be virtual, then it can't be a member function template, just overload it with the types you intend to support, then you can make them virtual.
You can't have a member function template which is virtual, but you can try implement friend generic function like this:
template <typename yourType>
yourType& succesorsFunction(const State &a, yourType &result){//Your return type can be without reference
//Your body
return result;
}
If you call your function for example with vector<State> a argument like this:
sucessorsFunction(b,a);// b is your State object
deduction process will automatically conclude that yourType is actually vector<State> type, which I think resolves your problem. Also, this arhitecture aloves you to create for example new class type MyVector (which holds arrays of States) and pass MyVector object to succesorsFunction.
This is just an elaboration to C.T's answer. Please remember that if you return a container of pointers then you will have to release them explicitly or use std::unique_ptr .
Just a FYI.. as you are from C# background.
You could use State or templatize it as well.
template<typename Type,
template< typename, typename = std::allocator<Type*> > class Container
>
Container<Type*> Successor(const Type& x)
{
Container<Type*> cont;
// something.
cont.push_back(new Type(x));
return cont;
}
and call it
vector<State*> states = Successor<State, vector>(State(10));