Какие шаблоны я должен специализировать для поддержки std :: get?
struct MyClass {
int a;
};
template <const size_t I>
struct MyContainer {
MyClass array[I];
};
Что я должен специализироваться, чтобы быть в состоянии сделать:
MyContainer<16> mc;
std::get<0>(mc);
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>;
Я предполагаю, что вы хотите реализовать некоторые алгоритмы, которым нужен доступ к произвольному массив типа контейнеры, использующие индексы времени компиляции и поэтому стремятся использовать некоторую функцию (например, 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;
}