-1

In this question here a solution was suggested on how to check for the value type of a generic container, e.g. check if a std::vector contains integral. Now, sometimes I might be passing 2D vectors i.e. containers of containers that eventually has either a floating point or integral type.

How can we modify the following concept to incorporate this, so that std::vector<std::vector<int>> won't fail if we expect it to contain integral types. In my application it won't make sense to go above std::vector<std::vector<int>> - matrix-like arrays. So the solution does not need to check for endless nested containers.

    template< typename U, typename Tin, typename Tout>
concept MyConditions =
    requires
    {
        typename U::value_type;
        typename Tin::value_type;
        typename Tout::value_type;
        requires std::integral<typename T::value_type>;
        requires std::floating_point<typename U::value_type>;
        requires std::floating_point<typename Tout::value_type>;
    };
ATK
  • 1,296
  • 10
  • 26
  • 2
    What do you mean by `so that std::vector> won't fail if we expect it to contain integral types.`? A `std::vector>` doesn't contain integral types. It contains vectors. How does `std::vector>` "fail"? – eerorika Apr 24 '21 at 02:03
  • How do I extract the value type of the most nested container? – ATK Apr 24 '21 at 02:05
  • Since you don't need to nest to arbitrary depth, you can write one concept for `ContainsIntegralType`, one concept for `ContainsContainsIntegralType`, and then one that's the union of both. – Nathan Pierson Apr 24 '21 at 02:19
  • 2
    @A2LBK: Whenever you write a concept, you should *first* write some code you are attempting to constrain with that concept. I am uncertain as to what code would be able to handle both `vector` and `vector>` without having a bunch of `if constexpr` conditions to differentiate the cases. – Nicol Bolas Apr 24 '21 at 02:48

1 Answers1

1

How do I extract the value type of the most nested container?

There is a type trait shown by user Evg in this answer.

Using that, this should work:

template< typename U, typename Tin, typename Tout>
concept MyConditions =
requires
{
    typename U::value_type;
    typename Tin::value_type;
    typename Tout::value_type;

    // note, I suspect that you have a typo in T,
    // which isn't declared. Did you mean Tin?
    requires std::integral<inner_type_t<T>>;
    requires std::floating_point<inner_type_t<U>>;
    requires std::floating_point<inner_type_t<Tout>>;
};
eerorika
  • 232,697
  • 12
  • 197
  • 326