This question combines several pieces of code and is a bit complicated, but I tried slimming it down as much as possible.
I am trying to use std::enable_if
typename function_traits<Lambda>::template arg<0>::type
^^^^^^^^
See this post for more information on dependent names and when template
or typename
is needed.
enable_if
typename = std::enable_if_t<condition>
should instead be
std::enable_if_t<condition>* = nullptr
as @Jarod42 mentioned. This is because the constructors would otherwise be identical and unable to be overloaded. That their default values differ doesn't change this fact. See this for more information.
Putting it together is
template<typename Lambda, std::enable_if_t<std::is_same_v<typename function_traits<Lambda>::template arg<0>::type, a_type>>* = nullptr>
A(const Lambda&);
Live
function_traits
won't work with either overloaded or templated operator()
, it can instead be replaced
template<typename T, typename... Args>
using return_type = decltype(std::declval<T>()(std::declval<Args>()...));
template<typename T, typename... Args>
using mfp = decltype(static_cast<return_type<T, Args...>(T::*)(Args...) const>(&T::operator()));
template<typename Lambda, mfp<Lambda, a_type> = nullptr>
A(const Lambda&);
To check if the callable can be called with the exact arguments without conversions.