I have a type trait
template <typename T, typename Enable = void>
struct is_binary_function : std::false_type {};
and its specialization
template <typename function_t>
struct is_binary_function<function_t,
std::enable_if_t<
!std::is_void_v<typename function_t::result_t> &&
!std::is_void_v<typename function_t::parameter1_t> &&
!std::is_void_v<typename function_t::parameter2_t> &&
function_t::isBinaryCallable
, function_t>
> : std::true_type {};
I am trying to identify classes, that have the public type definitions result_t
, parameter1_t
, and parameter2_t
, as well as a static constant isBinaryCallable
with the value true.
However, the following code does not output what I expect:
struct f {
using result_t = float;
using parameter1_t = float;
using parameter2_t = float;
static constexpr bool isBinaryCallable = true;
};
int main() {
using function_t = f;
std::cout << is_binary_function<f>::value << '\n'; //Error: outputs false, instead of true
std::cout << std::is_void_v<function_t::result_t> << '\n'; //false, as expected
std::cout << std::is_void_v<function_t::parameter1_t> << '\n'; //false, as expected
std::cout << std::is_void_v<function_t::parameter2_t> << '\n'; //false, as expected
std::cout << function_t::isBinaryCallable << '\n'; //true, as expected
std::cout << (!std::is_void_v<typename function_t::result_t> &&
!std::is_void_v<typename function_t::parameter1_t> &&
!std::is_void_v<typename function_t::parameter2_t> &&
function_t::isBinaryCallable) << '\n'; // true, as expected.
}
I guess my use of the metafunction pattern is flawed, but I can't figure out what I did wrong.
Why does the above metafunction not work as expected?
I am using Visual Studio 2017, set to the C++ 17 Standard.
std::enable_if_t<
!std::is_void_v<typename function_t::result_t> &&
!std::is_void_v<typename function_t::parameter1_t> &&
!std::is_void_v<typename function_t::parameter2_t> &&
function_t::isBinaryCallable
, function_t>
should be
std::enable_if_t<
!std::is_void_v<typename function_t::result_t> &&
!std::is_void_v<typename function_t::parameter1_t> &&
!std::is_void_v<typename function_t::parameter2_t> &&
function_t::isBinaryCallable
, void>
or
std::enable_if_t<
!std::is_void_v<typename function_t::result_t> &&
!std::is_void_v<typename function_t::parameter1_t> &&
!std::is_void_v<typename function_t::parameter2_t> &&
function_t::isBinaryCallable>
because is_binary_function<f>::value
is is_binary_function<f, void>::value
as specified in your primary template specialization of is_binary_function
(the second argument defaults to void
), meanwhile
std::enable_if_t<
!std::is_void_v<typename function_t::result_t> &&
!std::is_void_v<typename function_t::parameter1_t> &&
!std::is_void_v<typename function_t::parameter2_t> &&
function_t::isBinaryCallable
, function_t>
when passed function_t
as f
is f
, not void
. So it fails to match.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With