Tôi có nhu cầu sử dụng offsetof
từ một số template
với bộ chọn thành viên. Tôi đã tìm ra một cách, nếu bạn sẽ tha cú pháp vụng về:C++ Biên dịch bù thời gian bên trong một mẫu
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
Cách sử dụng là không hoàn hảo (gây phiền nhiễu lúc tốt nhất):
struct S
{
int x;
int y;
};
static_assert(offset_of<S, int, &S::x>() == 0, "");
static_assert(offset_of<S, int, &S::y>() == sizeof(int), "");
Dạng phi constexpr
là dễ dàng hơn sử dụng:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
tại những bất lợi rõ ràng rằng nó không được thực hiện tại thời gian biên dịch (nhưng dễ dàng hơn để sử dụng):
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
Điều tôi đang tìm kiếm là cú pháp giống như số không phải là constexpr
nhưng vẫn hoàn toàn biên dịch; tuy nhiên, tôi không thể đưa ra cú pháp cho nó. Tôi cũng sẽ hài lòng với một số offset_of<&S::x>::value
(như phần còn lại của các đặc điểm kiểu), nhưng không thể tìm ra phép thuật cú pháp cho nó.
Tôi đang cố gắng tìm ra nơi trong tiêu chuẩn mà nó nói rằng điều này làm những gì bạn mong đợi nó. Nhưng tôi không thể tìm thấy nó. –
Có gì sai với tiêu chuẩn ['offsetof'] (http://en.cppreference.com/w/cpp/types/offsetof)? –
@NicolBolas Tôi đoán là không. Không nên dereference của một 'nullptr' (và tôi nghĩ' -> 'đếm như dereference) được UB đã? Nhưng sau đó một lần nữa, phiên bản của vectơ 'offsetof' của VC không khác gì. Vì vậy, trong thực tế nó có thể là thực hiện khá định nghĩa hơn không xác định. –