Access function's parameter by argument position
-
Hello,
What I mean if the title is confusing:
void foo(_x,_y,_z)
{
x = param_list[0]; //x=_x
y = param_list[1]; //y=_y
z = param_list[2]; //z=_z
}
instead of:void foo(_x,_y,_z)
{
x = _x
y = _y
z = _z
}
-
@Ahzmandius a few approaches to this problem could be:
#include <utility> #include <tuple> #include <array> #include <iostream> struct A { void f1(int x_, int y_, int z_) { auto param_list = std::tuple<int, int, int>{ x_, y_, z_ }; x = std::get<0>(param_list); y = std::get<1>(param_list); z = std::get<2>(param_list); } void f2(int x_, int y_, int z_) { auto param_list = std::array<int, 3>{ x_, y_, z_ }; x = param_list[0]; y = param_list[1]; z = param_list[2]; } template <typename... Ts> void f3(Ts&&... args) { auto param_list = std::tuple<Ts...>{ std::forward<Ts>(args)... }; x = std::get<0>(param_list); y = std::get<1>(param_list); z = std::get<2>(param_list); } template <typename... Ts> void f4(Ts&&... args) { auto param_list = std::array<int, sizeof...(Ts)>{ std::forward<Ts>(args)... }; x = param_list[0]; y = param_list[1]; z = param_list[2]; } int x; int y; int z; }; auto main() -> int { A a; a.f1(1, 2, 3); std::cout << a.x << ", " << a.y << ", " << a.z << "\n"; a.f2(4, 5, 6); std::cout << a.x << ", " << a.y << ", " << a.z << "\n"; a.f3(7, 8, 9); std::cout << a.x << ", " << a.y << ", " << a.z << "\n"; a.f4(10, 11, 12); std::cout << a.x << ", " << a.y << ", " << a.z << "\n"; }For
f1andf3the parameter indices need to be compile time constants.f2andf3can use runtime dynamic indices, but might suffer from a bit more overhead during runtime. If performance is an issue, you should check the generated code - but modern compilers tend to optimize pretty well. I think dynamic indices can not be completely zero-overhead compared to directly referencing parameters by name.f3andf4are generic approaches for an arbitrary number of arguments. You might also want to restrict the allowed types for those functions. With C++20 this can easily be done with a concept, such as:#include <concepts> ... template <std::convertible_to<int>... Ts>With C++11 this can get a bit more cumbersome (maybe via
static_assertand such).
-
A function receives its parameters under the declared names and there is no alternative name for them. If you define the function foo
void foo (int x, int y, int z) { }the parameters of foo are only accessible via there names x, y and z. You can define an other type for the parameters like
void foo (std::array<int,3>& paras) { int x(paras[0]), y(paras[1]), z(paras[2]); }Just an remark for better code. Never use names with leading _ oder __, these names are reserved for the implementation (the compiler).
-
@john-0 sagte in Access function's parameter by argument position:
Just an remark for better code. Never use names with leading _ oder __, these names are reserved for the implementation (the compiler).
A single leading underscore is okay as long as it is not followed by an uppercase character. But it's easier to just avoid them altogether.
I tend to use trailing underscores instead.
-
@Finnegan sagte in Access function's parameter by argument position:
A single leading underscore is okay as long as it is not followed by an uppercase character.
For local variables/parameters, yes. In the global namespace anything starting with an underscore is reserved.
But it's easier to just avoid them altogether.
Agree.
I tend to use trailing underscores instead.
I decorate member variables instead of local variables/parameters. I use
m_as a prefix, because IMO it's much easier to see than using a suffix - especially one as subtle as a single_.But I think the important thing is to make it a habit to not use reserved identifiers.