Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I write a Container<T> trait and use its partial specialization as function params

Tags:

c++

templates

Let's say a class is a MyContainer<T> if it has

size_t size()
T& operator[](size_t index)
const T& operator[](size_t index)

and I want to write a template function that accept a specific version of MyContainer, for example any container that indexes int values and float values

float add(const MyContainer<int> &left, const MyContainer<float> &right);

and use it like

vector<int> a;
some_custom_vector<float> b;
float res = add(a, b);

How can I achieve that?

I cannot use auto because I want to specify inner type

// can not specify inner type
template<typename MyContainer>
float add(const MyContainer &left, const MyContainer &right);

// can not specify inner type either
auto add(const auto &left, const auto &right);

I also tried using template <template <class> class MyContainer>, but the compiler can't infer the inner template parameter.

like image 255
osennyaya Avatar asked Mar 12 '26 22:03

osennyaya


1 Answers

You want a concept:

#include <cstddef>
#include <concepts>

template <typename C, typename T>
concept MyContainer = requires(C &c, const C &cc, std::size_t n)
{
    { cc.size() } -> std::same_as<std::size_t>;
    { c[n] } -> std::same_as<T &>;
    { cc[n] } -> std::same_as<const T &>;
};

float add(const MyContainer<int> auto &left, const MyContainer<float> auto &right) {}

Note that, rather than specifying the custom container requirements like this, it's better to rely on built-in concepts from <ranges>:

template <typename C, typename T>
concept MyContainer = std::ranges::random_access_range<C>
    && std::same_as<std::ranges::range_value_t<C>, T>;

float add(MyContainer<int> auto &&left, MyContainer<float> auto &&right)

like image 63
HolyBlackCat Avatar answered Mar 14 '26 10:03

HolyBlackCat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!