Включить поддержку std :: get для класса

Какие шаблоны я должен специализировать для поддержки std :: get?

struct MyClass {
int a;
};

template <const size_t I>
struct MyContainer {
MyClass array[I];
};

Что я должен специализироваться, чтобы быть в состоянии сделать:

MyContainer<16> mc;
std::get<0>(mc);

8

Решение

std::get не является точкой настройки для стандартной библиотеки; три перегрузки шаблона функции (для pair, tuple а также array) явно не допускают пользовательских перегрузок, поэтому применяется 17.6.4.2.1p1, и добавление объявления собственной перегрузки шаблона функции является неопределенным поведением.

Обратите внимание, что get как неквалифицированный название является точка настройки начиная с C ++ 17; он используется декларация структурированного связывания протокол для доступа к кортежоподобным элементам; но это как неквалифицированное имя, а не полное имя std::get,

Тем не менее, если вы мы написать:

namespace std {
template<size_t I, size_t N> MyClass &get(MyContainer<N> &c) { return c.array[I]; }
}

и аналогично для перегруженных ссылок rvalue и const reference ваша программа, вероятно, будет работать так, как вы ожидаете.

Тем не менее, нет смысла видеть, как стандарт уже поставляет array:

template<size_t N> using MyContainer = std::array<MyClass, N>;
13

Другие решения

Я предполагаю, что вы хотите реализовать некоторые алгоритмы, которым нужен доступ к произвольному массив типа контейнеры, использующие индексы времени компиляции и поэтому стремятся использовать некоторую функцию (например, std::get) чтобы равномерно выполнить эту задачу ?!
В этом случае это тот же бизнес, что и begin а также end доступно для вашего класса. Вы просто объявляете функцию get в пространстве имен вы объявили свой контейнерный класс и позволили ADL выполнять свою работу.

    template <unsigned I, unsigned N>
MyClass& get (MyContainer<N>& c) { return c.array[I]; }

template <unsigned I, unsigned N>
MyClass const& get (MyContainer<N> const& c) { return c.array[I]; }

В вашем алгоритме вы просто используете get (без std префикс пространства имен) и ADL будут вызывать правильную функцию. Итак, для стандартных структур, таких как array, tuple а также pair std::get вызывается и для вашего контейнера get функция, которую вы предоставили.

    int main(){
std::array<int, 3> a {{0,1,2}};
auto t = std::make_tuple(0.0, 1.0f, 2);
auto p = std::make_pair('0', 4.4);
MyContainer<3> c;

std::cout << get<1>(a) << std::endl;
std::cout << get<1>(t) << std::endl;
std::cout << get<1>(p) << std::endl;
std::cout << get<1>(c).a << std::endl;

return 0;
}

пример

0

По вопросам рекламы [email protected]