mercredi 25 mars 2015

Deducing parameter types from bind-expression

In order to deduce the parameter types for functional objects I have created helper classes that allow me to get the according std::function<...> for generic parameters. The helper classes right now look like this:



template<typename T>
class functional_traits : public functional_traits<decltype(&T::operator())> {

};

template<typename Ret, typename ClassType, typename... Args>
class functional_traits < Ret(ClassType::*)(Args...) const > {
public:
typedef std::function<Ret(Args...)> FunctionType;
};


The same version as the last exists also with a non const specialization. You can use this like that:



template<typename T>
void foo(const T& value) {
auto function = (typename functional_traits<T>::FunctionType)(value);
}

foo([](int a) { return a * 2.3f; });


and you will have function as std::function<float (int)>. This is fine since according to the standard a lambda is required to end up as a C++ non-union class object with a member operator () that is either const or non-const (when the lambda is mutable)


So much for what is working ;)


The problem now is when I'm using foo(std::bind(someMethod, std::placeholders::_1)). The return type of std::bind is not specified by the standard, its not even mandatory that its featuring an operator (). In Visual Studio and gcc there is such an operator but it has 4 overloads (one const volatile, one volatile, one const and one without modifiers). Now of course the decltype(&T::operator()) fails because it doesnt know which overload I want.


I have tried using typedes to convert T into an always const volatile type and then hoping that &T_cv::operator() would always select the const volatile version of the operator, but that is not the case.


So my problem or question is: Is there a way to get the arguments of a result from std::bind with partial specialization? I assume the existence of an operator () as given since I'm only interested in Visual Studio (and maybe a lot later gcc).


Aucun commentaire:

Enregistrer un commentaire