I'm using VS2015 and I'm playing with std::function and std::bind I found a strange errors.
I have a 2 chained bind operation:
int main()
{
auto func1 = [](int i) -> int {
return i + 1;
};
auto func2 = [](float f, function<int(int)>&& func) -> float {
return f + func(f);
};
auto func2_instance = std::bind(func2, std::placeholders::_1, func1);
cout << func2_instance(0.2) << endl;
auto func3 = [](double d, function<float(float)>&& func)->double {
return d + func(d);
};
//doesn't work
auto func3_instance = std::bind(func3, std::placeholders::_1, std::move(func2_instance));
//works
auto func3_instance = std::bind(func3, std::placeholders::_1, [funcmv = std::move(func2_instance)](float a)->float{
return funcmv(a);
});
func3_instance(0.2);
}
the error I got is related to line func3_instance(0.2)
D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\type_traits(1468): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'
Could you please help? What I miss related to std::bind?
Merci in advance.
If you add code, stolen from here:
Why is there no std::protect?
template<typename T>
struct protect_wrapper : T
{
protect_wrapper(const T& t) : T(t) {}
protect_wrapper(T&& t) : T(std::move(t)) {}
};
template<typename T>
typename std::enable_if< !std::is_bind_expression< typename std::decay<T>::type >::value,
T&& >::type
protect(T&& t)
{
return std::forward<T>(t);
}
template<typename T>
typename std::enable_if< std::is_bind_expression< typename std::decay<T>::type >::value,
protect_wrapper<typename std::decay<T>::type > >::type
protect(T&& t)
{
return protect_wrapper<typename std::decay<T>::type >(std::forward<T>(t));
}
and modify your line to:
auto func3_instance = std::bind(func3, std::placeholders::_1, protect( func2_instance));
the code works ( for me ).
Related
I have a method that takes an index-able object as a template parameter, something like:
template <typename OBJ>
int foo(int n, OBJ o)
{
int x = 0;
for (int i = 0; i < n; ++i) {
x += o[i];
}
return x;
}
Is there a way I can pass a lambda function in for the o parameter? In other words, having the lambda be call-able via the [] operator rather than the () operator?
template<class F>
struct square_bracket_invoke_t {
F f;
template<class T>
auto operator[](T&& t)const
-> typename std::result_of< F const&(T&&) >::type
{ return f(std::forward<T>(t)); }
};
template<class F>
square_bracket_invoke_t< typename std::decay<F>::type >
make_square_bracket_invoke( F&& f ) {
return {std::forward<F>(f)};
}
Live example.
Code is C++11 and has basically zero overhead.
int main() {
std::cout << foo( 6, make_square_bracket_invoke([](int x){ return x; } ) ) << "\n";
}
result is 0+1+2+3+4+5 aka 15.
Is this a good idea? Maybe. But why stop there?
For max amusement:
const auto idx_is = make_square_bracket_invoke([](auto&&f){return make_square_bracket_invoke(decltype(f)(f));});
int main() {
std::cout << foo( 6, idx_is[[](int x){ return x; }] ) << "\n";
}
You can do that by:
Creating a class template, a functor, that has the operator[] defined.
Implementing the operator[] in terms of the operator() of a std::function.
Storing the lambda in a wrapped std::function as a member variable of the class template.
Here's a demonstrative program.
#include <iostream>
#include <functional>
template <typename OBJ>
int foo(int n, OBJ o)
{
int x = 0;
for (int i = 0; i < n; ++i) {
x += o[i];
}
return x;
}
template <typename> struct Functor;
template <typename R> struct Functor<R(int)>
{
using ftype = std::function<R(int)>;
Functor(ftype f) : f_(f) {}
R operator[](int i) const { return f_(i); }
ftype f_;
};
int main()
{
Functor<int(int)> f = {[](int i) -> int {return i*i;}};
std::cout << foo(10, f) << std::endl;
}
and its output
285
Live demo
PS
Functor is not the appropriate name here. It does not overload the function call operator. I suspect there is a more appropriate name.
Well, if it helps, here's a way to forward a wrapper class's operator[] to your lambda's operator().
template<class F>
struct SubscriptWrapper_t {
F f_;
template<class T> auto operator[](T const& t_) const -> decltype(f_(t_)) {
return f_(t_);
}
};
template<class F>
SubscriptWrapper_t<typename std::decay<F>::type> SubscriptWrapper(F&& f_) {
return{std::forward<F>(f_)};
}
I use wrappers like this a lot. They're convenient, and they don't seem to have any computational overhead, at least when compiled by GCC. You can make one for at or even make one for find.
EDIT: Updated for C++11 (and updated to be able to return a reference)
A sketch of a wrapper type that would do this.
template<typename UnaryFunction>
class index_wrapper
{
public:
index_wrapper(UnaryFunction func) : func(std::move(func)) {}
template<typename T>
std::invoke_result_t<UnaryFunction, T> operator[](T&& t)
{ return func(std::forward<T>(t)); }
private:
UnaryFunction func;
};
With usage
#include <iostream>
template <typename OBJ>
int foo(int n, OBJ o)
{
int x = 0;
for (int i = 0; i < n; ++i) {
x += o[i];
}
return x;
}
int main()
{
index_wrapper f([](int i) -> int { return i*i; });
std::cout << foo(10, f) << std::endl;
}
You might want to restrict it to a single parameter type, so that you can provide member type aliases similar to std::vector::reference et.al.
So I was Playing around with c++11 Varidiacs, and I wanted to create a thing called CallClass, basically a class that warps a function, for later call,when all variables are set(truly I have No Idea If It can Be Useful):
#include <tuple>
template <typename OBJ,typename F,typename... VARGS>
class CallClass
{
public:
CallClass(OBJ& object,F callFunction)
:_object(&object),_func(callFunction)
{ }
CallClass(const CallClass& other)
:_func_args(other._func_args)
,_object(other._object)
,_func(other._func)
{ }
template <size_t INDEX>
auto get(){ return std::get<INDEX>(_func_args); }
template <size_t INDEX,typename T>
void set(const T& val){ std::get<INDEX>(_func_args) = val; }
template <size_t INDEX,typename T>
void set(T&& val){ std::get<INDEX>(_func_args) = val; }
auto Call()
{
//throws segmentation Fault Here
return InnerCall<0>(_func_args);
}
virtual ~CallClass() {}
protected:
private:
std::tuple<VARGS...> _func_args;
OBJ* _object;
F _func;
template <size_t INDEX,typename... ARGS>
auto InnerCall(std::tuple<VARGS...>& tup,ARGS... args)
{
auto arg = std::get<INDEX>(tup);
return InnerCall<INDEX + 1>(tup,args...,arg);
}
template <size_t INDEX,VARGS...>
auto InnerCall(std::tuple<VARGS...>& tup,VARGS... args)
{
return (_object->*_func)(args...);
}
};
Now when I try to compile(compiling using IDE:code::blocks, configured to use MINGW On windows ), it prints Compiler:Segmentation Fault, anybody any Ideas?
Usage:
class obj{
public:
obj(int a)
:_a(a)
{ }
virtual ~obj() {}
int add(int b,int c){
return _a + b + c;
}
private:
int _a;
};
int main(){
obj ob(6);
CallClass<obj,decltype(obj::add),int,int> callAdd(ob,obj::add);
callAdd.set<0,int>(5);
callAdd.set<1,int>(7);
cout << "result is " << callAdd.Call() << endl;
return 0;
}
After a Bit of a search i stumbled upon a similar issue, in a way.
apparently the way I'm unpacking the tuple is an issue, so i decided to use a different approach as shown in: enter link description here
had to add a few changes to suit my needs:
changes:
namespace detail
{
template <typename OBJ,typename F, typename Tuple, bool Done, int Total, int... N>
struct call_impl
{
static auto call(OBJ& obj,F f, Tuple && t)
{
return call_impl<OBJ,F, Tuple, Total == 1 + sizeof...(N), Total, N..., sizeof...(N)>::call(obj,f, std::forward<Tuple>(t));
}
};
template <typename OBJ,typename F, typename Tuple, int Total, int... N>
struct call_impl<OBJ,F, Tuple, true, Total, N...>
{
static auto call(OBJ& obj,F f, Tuple && t)
{
return (obj.*f)(std::get<N>(std::forward<Tuple>(t))...);
}
};
}
// user invokes this
template <typename OBJ,typename F, typename Tuple>
auto call(OBJ& obj,F f, Tuple && t)
{
typedef typename std::decay<Tuple>::type ttype;
return detail::call_impl<OBJ,F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(obj,f, std::forward<Tuple>(t));
}
and changed Call():
auto Call()
{
std::tuple<VARGS...> func_args = _func_args;
return call(*_object,_func, std::move(func_args));
}
I will probably make a few more changes, like passing the tuple as a reference, and making the structs a part of my class.
How can I have this effect without the arbitrary typedefs?
#include <type_traits>
#include <iostream>
typedef int Primary;
typedef float Secondary;
template<Class C, std::enable_if<std::is_same<Class, Primary>::value || std::is_same<Class, Secondary>::value> = 0>
class Entity {
public:
template<std::enable_if<std::is_same<Class, Secondary>::value>::type = 0>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
};
int main() {
Entity<Secondary> e;
e.onlyLegalForSecondaryEntities();
return 0;
}
Is there a more elegant way to produce this so that Entity can only be instantiated with Primary or Secondary as template arguments?
After fixing the errors in your code:
In C++1z you can easily roll a trait is_any with std::disjunction:
template<typename T, typename... Others>
struct is_any : std::disjunction<std::is_same<T, Others>...>
{
};
In C++11, you can implement disjuncation as
template<class...> struct disjunction : std::false_type { };
template<class B1> struct disjunction<B1> : B1 { };
template<class B1, class... Bn>
struct disjunction<B1, Bn...>
: std::conditional<B1::value != false, B1, disjunction<Bn...>>::type { };
Then define your class template as
template<class C, typename std::enable_if<is_any<C, Primary, Secondary>::value>::type* = nullptr>
class Entity {
public:
template<typename std::enable_if<std::is_same<C, Secondary>::value>::type* = nullptr>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
};
demo
You can take this further and make enable_if_any alias that would resolve to void if possible:
template<typename This, typename... Elems>
using enable_if_is_any = typename std::enable_if<is_any<This, Elems...>::value>::type;
template<class C, enable_if_is_any<C, Primary, Secondary>* = nullptr>
class Entity {
public:
template<typename std::enable_if<std::is_same<C, Secondary>::value>::type* = nullptr>
void onlyLegalForSecondaryEntities() {
std::cout << "Works" << std::endl;
}
};
demo
I have some code which, very much simplified, looks somewhat like this:
#include <iostream>
#include <type_traits>
namespace X {
struct Foo {int x;};
struct Bar {int x;};
template <typename T , typename = typename std::enable_if<
std::is_same<decltype(T::x),int>::value
>::type>
std::ostream & operator<<(std::ostream & os, const T&) {
return os;
}
}
namespace Y {
struct Faa : X::Foo {int y;};
struct Baz {int x; int y;};
template <typename T , typename = typename std::enable_if<
std::is_same<decltype(T::x),int>::value &&
std::is_same<decltype(T::y),int>::value
>::type>
std::ostream & operator<<(std::ostream & os, const T&) {
return os;
}
}
int main() {
// Everything is ok
X::Foo x;
std::cout << x;
Y::Baz k;
std::cout << k;
// Problems..
Y::Faa y;
// std::cout << y; // <--operator is ambiguous
Y::operator<<(std::cout, y);
return 0;
}
Is there any way to avoid the ambiguous operator for Y::Faa and having to manually specify Y::operator<<? If not, why?
Two functions have a conflict because conditions on their arguments have non-empty intersection (actually, 1st supersedes 2nd). Function overloading works only if signatures are different. So, to solve this we have 2 options:
Change conditions so that they have empty intersection (manually forbid having y field by adding && !sfinae_has_member_y<T>::value condition to the 1st enable_if)
template<typename T>
struct sfinae_has_member_y {
static int has(...);
template<typename U = T, typename = decltype(U::y)>
static char has(const U& value);
enum { value = sizeof(char) == sizeof(has(std::declval<T>())) };
};
OR use another C++ feature that supports arguments overlapping, like struct/class template specialization. If you replace bool with int, other fields may be added too:
template<typename T, bool>
struct Outputter {
};
template<typename T>
struct Outputter<T, false> {
static std::ostream & output(std::ostream & os, const T&) {
os << "x";
return os;
}
};
template<typename T>
struct Outputter<T, true> {
static std::ostream & output(std::ostream & os, const T&) {
os << "y";
return os;
}
};
template<typename T, typename = std::enable_if_t<std::is_same<decltype(T::x), int>::value>>
std::ostream & operator<<(std::ostream & os, const T& a) {
return Outputter<T, sfinae_has_member_y<T>::value>::output(os, a);
}
I have the following code:
#include <iostream>
#include <functional>
class test
{
public:
typedef std::function<bool(int)> Handler;
void handler(Handler h){h(5);}
};
class test2
{
public:
template< typename Ret2, typename Ret, typename Class, typename Param>
inline Ret2 MemFn(Ret (Class::*f)(Param), int arg_num)
{
if (arg_num == 1)
return std::bind(f, this, std::placeholders::_1);
}
bool f(int x){ std::cout << x << std::endl; return true;}
};
int main()
{
test t;
test2 t2;
t.handler(t2.MemFn<test::Handler>(&test2::f, 1));
return 0;
}
It works as expected.
I would like to be able to call this:
t.handler(t2.MemFn<test::Handler>(&test2::f));
instead of
t.handler(t2.MemFn<test::Handler>(&test2::f, 1));
Basically I need MemFn to determine in runtime what Handler expects as the number of arguments.
Is that even possible?
You may create some type_traits to have your info, something like:
template <typename T> struct function_trait;
template <typename Ret, typename ... Args>
struct function_trait<std::function<Ret(Args...)>>
{
static constexpr std::size_t args_count = sizeof...(Args);
};
And so your method may look like:
template<typename Ret2, typename Ret, typename Class, typename Param>
inline Ret2 MemFn(Ret (Class::*f)(Param))
{
if (function_trait<Ret2>::args_count == 1)
return std::bind(f, this, std::placeholders::_1);
throw std::runtime_error("invalid number of arguments");
}