Во-первых, как и просили, ваша цель недостижима, так как тип a
воздействует на a
внутри B
:
struct B
{
int some_variables[256];
A</* offset of a inside B */> a;
};
Это выравнивание .
Вы можете использовать стандартный макрос offsetof
.Это подразумевает две вещи:
- Поскольку
offsetof(type, member)
четко определен только для стандартного макета type
с, тип оболочки должен быть стандартного макета, - и поскольку
offsetof
можно "вызывать" только для полных типов, его статически вычисляемый результат может быть установлен только для подобъекта динамически;он не может быть параметром не типового шаблона, но может быть аргументом конструктора.
Полная программа
#include <cassert>
#include <cstdint>
#include <cstddef>
struct Location
{
Location(std::size_t offset) : offset_(offset) {}
std::size_t offset_;
operator std::intptr_t () const { return reinterpret_cast<std::intptr_t>(this) - offset_; }
};
struct SomeType
{
int some_variables[256];
Location location = offsetof(SomeType, location);
};
int main()
{
SomeType obj;
assert(reinterpret_cast<std::intptr_t>(&obj) == obj.location); // does pass
}
live demo
Но, как вы прокомментировали, это совершенно бесполезно, поскольку Location
можно просто определить как
template<class T>
struct Location
{
Location(T* location) : location_(location) {}
T* location_;
operator T* () const { return location; }
};
и инициализировать с помощью Location location = this;
.