Есть ли какой-либо простой способ получить кусочек передающих аргументов не в определенном порядке без повторной перегрузки?
Да, вы можете это сделать, но поскольку вы не сказали, каково ваше точное использование этой функции, я не могу дать вам общее решение. В любом случае, для всех людей, заявляющих в комментариях, что поведение, которое требуется автору вопроса, неверно, плохо, глупо и т. Д., Пожалуйста, рассмотрите следующий фрагмент кода, который работает, и я вижу потенциал в этом.
Предположим, что у нас есть класс, у которого есть поля, в которых хранятся некоторые значения, и мы хотим иметь сеттеры (и, вероятно, получатели) для доступа к этим значениям (для ясности я представил только минимальную версию).
Таким образом, этот класс будет:
struct A {
int g1 {};
int g2 {};
int g3 {};
};
Этот класс не имеет сеттеров или добытчик, потому что мы собираемся, чтобы обернуть его в другом классе, в Data
классе.
struct Data {
template <typename... Ts>
void set (Ts&&... ts) {
set_impl (std::forward<Ts> (ts)...);
}
A a;
private:
template <typename T>
void set_impl (T&& t) {
a.*T::mem = t.v; // (X)
}
template <typename T, typename K, typename... Ts>
void set_impl (T&& t, K&& k, Ts&&... ts) {
set_impl (std::forward<T> (t));
set_impl (std::forward<K> (k), std::forward<Ts> (ts)...);
}
};
Так вот у нас есть класс, который имеет set
функцию-член, которая принимает произвольное число аргументов или и каждый из них может быть (и в этом примере должны быть) различного типа. Чтобы установить A
полей, которые вы видите в (X)
, вам необходимо передать объект типа, который имеет указатель на член A
. Поэтому, пожалуйста, взгляните на следующие классы.
struct G {
G (int c = {}) : v {c} {}
int v;
};
struct G1 : G { using G::G; static constexpr int A::* mem = &A::g1; };
struct G2 : G { using G::G; static constexpr int A::* mem = &A::g2; };
struct G3 : G { using G::G; static constexpr int A::* mem = &A::g3; };
Все Gx
функции здесь только для установки значения A
полей и каждый из них знает, какое поле будет установлено.
Вспомогательная функция для показа результата является:
void show (const A& v) {
std::cout << "g1 = " << v.g1 << std::endl;
std::cout << "g2 = " << v.g2 << std::endl;
std::cout << "g3 = " << v.g3 << std::endl;
}
И, наконец, использование:
Data d;
d.set (G1 {10}, G2 {20}, G3 {30});
show (d.a);
Data p;
p.set (G3 {40}, G1 {-30}, G2 {120});
show (p.a);
, который дает нам выход:
g1 = 10
g2 = 20
g3 = 30
g1 = -30
g2 = 120
g3 = 40
Как я уже сказал, я не знаю, соответствует ли это вашим потребностям, но это всего лишь пример, как это сделать, и это может быть полезно для вас.
Несмотря на то, что значения, заданные в заданном порядке (в сочетании с произвольным количеством значений), имеют преимущество, что вы можете установить только те значения, которые необходимы.
Просто из любопытства, почему кто-то хочет передать параметры функции в неправильном порядке? – DyZ
Зачем вам нужна эта гибкость? Если вы его построите, вы можете передать их в определенном порядке. –
, если вы знаете, что функция принимает 3 разных типа аргументов, было бы нецелесообразно передавать их в любом порядке, а не проверять функцию prototyoe? – Arash