c++c++20boost-mp11

Why does this boost mp11 mp_count_if_q code always return 0?


I wonder why the following code does not work as expected(is_numeric is always 0).

#include <type_traits>
#include <utility>
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/bind.hpp>
#include <boost/mp11/tuple.hpp>

using namespace boost::mp11;

using NumericTypes = std::tuple<short, unsigned short, int, unsigned int, 
                                long int, unsigned long int, 
                                long long int, unsigned long long int, 
                                float, double, long double>;
template<typename T>
static constexpr int is_numeric = mp_count_if_q<NumericTypes,
mp_bind_front<std::is_same,std::remove_cvref<T>>>::value;

int main(){
    return is_numeric<char>+2*is_numeric<int>;
}

My assumption is that while trying to get stuff to compile I made some dumb mistake(I used _q version just because I could not get mp_count_if to work), but I see nothing obvious, and from what I found tests/doc do not contain something similar to my relatively complex example.

FWIW bind front seems to work as I expect it to work...

template<typename T>
using is_int = mp_bind_front<std::is_same,int>::fn<T>;
static_assert(!is_int<float>());
static_assert(is_int<int>());

Solution

  • You are comparing against std::remove_cvref<T>, which itself is a type and rightfully not a numerical. But I assume you want to test against the type produced from the trait: std::remove_cvref<T>::type, or better std::remove_cvref_t<T>.

    Now

    template<typename T>
    static constexpr int is_numeric = mp_count_if_q<NumericTypes,
    mp_bind_front<std::is_same,std::remove_cvref_t<T>>>::value;
    

    works as expected!