Long time no see and Input Capture

The Partridge Family were neither partridges nor a family. Discuss.
albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Long time no see and Input Capture

Post by albinopapa » November 21st, 2018, 9:30 pm

Going back to your code, as an example when I was writing a custom allocator, I had to use that syntax for rebinding the allocator type.

using NodeAllocatorType = std::allocator_traits::template rebind_allocator<Node<T>>;

or something like that.

dependent name
Look near the bottom under: The template disambiguator for dependent names
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Long time no see and Input Capture

Post by cameron » November 21st, 2018, 10:24 pm

Ah, yeah that was the problem. Thanks papa.

I was referencing a templated type so I needed both the typename and template keywords.

Code: Select all

template<CallingConvention CC, typename RT, typename... Args>
using PFunc = typename CCHelper<CC>::template PFunc<RT, Args...>;
I've just been away from this too long and feel kinda like I'm guessing the correct syntax for certain things lol. been on c++ ref way more than I feel I should considering how much c++ I've done.
Computer too slow? Consider running a VM on your toaster.

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Long time no see and Input Capture

Post by cameron » November 21st, 2018, 11:25 pm

Okay, so I pretty much got my function class sorted out.
The problem now is with my FunctionS constructors.

I can't seem to get SFINAE overload resolution to work because of the variadic nature of the template arguments and constructor parameters. I was going to use return type but constructors dont have a return type so I am at a loss here...

Code: Select all

template<typename RT>
class FunctionS
{
public:
	template<typename FUNC, typename... Args>
	FunctionS(FUNC&& func, Args&&... args, typename std::enable_if_t<!is_function_ptr<FUNC>::value>* = nullptr)
		: action([func, args...]()->RT {return func(std::forward<Args>(args)...); })
	{}

	template<typename FUNC, typename... Args>
	FunctionS(FUNC&& func, Args&&... args, typename std::enable_if_t<is_function_ptr<FUNC>::value>* = nullptr)
		: action([func, args...]()->RT {return (*func)(std::forward<Args>(args)...); })
	{}

	template<typename FUNC, typename O, typename... Args>
	FunctionS(FUNC&& func, O* o, Args&&... args, typename std::enable_if_t<std::is_member_function_pointer<FUNC>::value>* = nullptr)
		: action([func, o, args...]()->RT {return (o->*func)(std::forward<Args>(args)...); })
	{}

	template<typename FUNC, typename O, typename... Args>
	FunctionS(FUNC&& func, O& o, Args&&... args, typename std::enable_if_t<std::is_member_function_pointer<FUNC>::value>* = nullptr)
		: action([func, &o, args...]()->RT {return (o.*func)(std::forward<Args>(args)...); })
	{}

	operator bool() const
	{
		return action.operator bool();
	}

	auto operator()() const -> RT
	{
		return action();
	}

private:
	std::function<RT()> action;
};
Computer too slow? Consider running a VM on your toaster.

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Long time no see and Input Capture

Post by cameron » November 22nd, 2018, 1:58 am

This appears to sorta work but I dont like the need for the (extra) move assignment. It also seems to have a hard to deciding which overload to choose.

Code: Select all

template<typename RT>
class FunctionS
{
public:
	using Action = std::function<RT()>;

	template<typename... Args>
	FunctionS(Args&&... args)
		:
		action(MakeFunc<Args...>(std::forward<Args>(args)...))
	{}

	operator bool() const
	{
		return action.operator bool();
	}

	auto operator()() const -> RT
	{
		return action();
	}

private:
	template<typename FUNC, typename... Args>
	std::enable_if_t<!is_function_ptr<FUNC>::value, Action> MakeFunc(FUNC&& func, Args&&... args)
	{
		return[func, args...]()->RT {return func(std::forward<Args>(args)...); };
	}

	template<typename FUNC, typename... Args>
	std::enable_if_t<is_function_ptr<FUNC>::value, Action> MakeFunc(FUNC&& func, Args&&... args)
	{
		return[func, args...]()->RT {return (*func)(std::forward<Args>(args)...); };
	}

	template<typename FUNC, typename O, typename... Args>
	std::enable_if_t<std::is_member_function_pointer<FUNC>::value, Action> MakeFunc(FUNC&& func, O* o, Args&&... args)
	{
		return[func, o, args...]()->RT {return (o->*func)(std::forward<Args>(args)...); };
	}

	template<typename FUNC, typename O, typename... Args>
	std::enable_if_t<std::is_member_function_pointer<FUNC>::value, Action> MakeFunc(FUNC&& func, O& o, Args&&... args)
	{
		return[func, &o, args...]()->RT {return (o.*func)(std::forward<Args>(args)...); };
	}

	Action action;
};
Computer too slow? Consider running a VM on your toaster.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Long time no see and Input Capture

Post by albinopapa » November 22nd, 2018, 6:38 am

You had something before that worked for constructors I though.

Code: Select all

template<
    typename T, 
    typename = std::enable_if_t<is_function_ptr<T>::value, int>,0>
MyClass( T&& fnptr )
    :
action( std::forward<T>( fnptr ) )
{}
You have to use a dummy template parameter.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Long time no see and Input Capture

Post by albinopapa » November 22nd, 2018, 6:39 am

I might have the = in the wrong place, it might go before the 0 at the end.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Long time no see and Input Capture

Post by albinopapa » November 22nd, 2018, 6:41 am

I was referencing a templated type so I needed both the typename and template keywords.
I didn't think you'd need the typename portion, since the resolution was on a templated type not a regular type, but whatevs, glad it helped.

I messed around with templates quite a bit a month or two ago, so I learned a lot, but am quickly beginning to forget all the subtleties.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Long time no see and Input Capture

Post by cameron » November 22nd, 2018, 7:27 am

I didn't think you'd need the typename portion, since the resolution was on a templated type not a regular type, but whatevs, glad it helped.
It is necessary, as far as I can tell. I tried without it and it wouldn't compile.
You have to use a dummy template parameter.
Not possible with a parameter pack as the ... has to be at the end. I tried for a while with both parameter and template parameter SFINAE and I couldn't get it working because of the parameter pack.

As a quick test this wont compile; Im not quite sure why right now

Code: Select all

template<typename RT>
class FunctionS
{
public:
	using Action = std::function<RT()>;

	template<typename... Args>
	FunctionS(Args&&... args)
		:
		action(MakeFunc<Args...>(std::forward<Args>(args)...))
	{}

	operator bool() const
	{
		return action.operator bool();
	}

	auto operator()() const -> RT
	{
		return action();
	}

private:
	template<typename FUNC, typename... Args>
	std::enable_if_t<!is_function_ptr<FUNC>::value, Action> MakeFunc(FUNC&& func, Args&&... args)
	{
		return[func, args...]()->RT {return func(std::forward<Args>(args)...); };
	}

	template<typename FUNC, typename... Args>
	std::enable_if_t<is_function_ptr<FUNC>::value, Action> MakeFunc(FUNC&& func, Args&&... args)
	{
		return[func, args...]()->RT {return (*func)(std::forward<Args>(args)...); };
	}

	template<typename FUNC, typename O, typename... Args>
	std::enable_if_t<std::is_member_function_pointer<FUNC>::value, Action> MakeFunc(FUNC&& func, O* o, Args&&... args)
	{
		return[func, o, args...]()->RT {return (o->*func)(std::forward<Args>(args)...); };
	}

	template<typename FUNC, typename O, typename... Args>
	std::enable_if_t<std::is_member_function_pointer<FUNC>::value, Action> MakeFunc(FUNC&& func, O& o, Args&&... args)
	{
		return[func, &o, args...]()->RT {return (o.*func)(std::forward<Args>(args)...); };
	}

	Action action;
};

struct A
{
	int Do(int, int) const
	{

	}
};

A a;
//FunctionS<void> f { &A::Do, &a, 5, 6 };
FunctionS<void> f = FunctionS<void>::FunctionS<decltype(&A::Do), A, int, int>( &A::Do, &a, 5, 6 );
Computer too slow? Consider running a VM on your toaster.

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Long time no see and Input Capture

Post by cameron » November 22nd, 2018, 10:13 pm

Seems it ended up being an issue with the lambda capture. Had to do a hack with std::tuple and std::apply to get perfect forwarding with lambda capture.
Computer too slow? Consider running a VM on your toaster.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Long time no see and Input Capture

Post by albinopapa » November 23rd, 2018, 2:46 am

First find:

Code: Select all

	template<typename FUNC, typename... Args>
	std::enable_if_t<!is_function_ptr<FUNC>::value, Action>
		MakeFunc( FUNC&& func, Args&&... args )
	{
		return[ func, args... ]()->RT {return func( std::forward<Args>( args )... ); };
	}
This is actually going to be a catch all for anything NOT a function pointer...which I'm guessing also includes member function pointers, so this one is incorrectly evaluated and chosen.

Ok, this is old information, but commenting this out did allow me to start looking into the parameter pack and the lambda capture. The way you had it would have been copy by value, so nice catch.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply