As the title says and without any additional parameters in Request() while keeping it clean. Below is an example:
struct CPerson
{
void Request();
}
void CPerson::Request()
{
// get index
/* EXAMPLES
serverinfo* info;
server.GetInfo(&info, index);
cout << info.username << "\n";
*/
}
CPerson person[64];
int main()
{
for (int i = 0; i < 64; i )
person[i].Request(); // i = current index
return 0;
}
edit: fixed title
CodePudding user response:
In this specific case, as long as you can guarantee that CPerson
is only ever stored in this array, you can use std::distance()
to get the index, since this
happens to be a valid iterator into the array.
It's effectively the same thing as just doing this - person
, but standard library implementations can (and often do) have additional safety nets in debug builds at no performance cost for release builds.
Even with that additional safety, manual error checking to validate the assumption that this
is part of person
is still a good idea. For this, you'll want to use std::less
(as opposed to the relational operators), as it's guaranteed to be globally valid even for pointers that are not inside the array.
// C 11 and up.
#include <iterator>
#include <stdexcept>
struct CPerson
{
void Request();
};
CPerson person[64];
void CPerson::Request()
{
// possibly an assert() instead...
if(std::less<CPerson*>{}(this, std::begin(person)) ||
!std::less<CPerson*>{}(this, std::end(person))) {
throw std::out_of_range("not part of person");
}
std::size_t index = std::distance(std::begin(person), this);
}
In C 20, you can be cleanly more generic about it, which will let person
be any contiguous range, like std::vector
for example:
// C 20 and up.
#include <ranges>
#include <stdexcept>
#include <vector>
struct CPerson
{
std::size_t Index() const;
void Request();
};
CPerson person[64];
// Or possibly
// std::vector<CPerson> person;
std::size_t CPerson::Index() const
{
static_assert(std::ranges::contiguous_range<decltype(person)>);
const CPerson* person_b = std::to_address(std::ranges::begin(person));
const CPerson* person_e = std::to_address(std::ranges::end(person));
if(std::less{}(this, person_b) ||
!std::less{}(this, person_e)) {
throw std::out_of_range("not part of person");
}
return std::distance(person_b, this);
}
void CPerson::Request() {
auto i = Index();
}