2013-09-26 74 views
7

Chuẩn C++ 11 chỉ định đặc điểm kiểu std::alignment_of<T>, chỉ trả về giá trị alignof(T).Đặc điểm kiểu tiêu chuẩn cho giá trị sizeof (T)

Có một đặc điểm tương tự cho nhà điều hành sizeof không? Tôi chỉ thiếu nó, hoặc là nó chỉ bị mất trong tiêu chuẩn, hoặc là có một số lý do kỹ thuật tối nghĩa lý do tại sao nó không được chỉ định?

Rõ ràng nó là tầm thường để tạo ra một đặc điểm như vậy, nhưng tôi không thể tưởng tượng nó sẽ không được xem xét khi giới thiệu std::alignment_of.

Đối với ngữ cảnh, tôi có đặc điểm kiểu tùy chỉnh mà tôi sử dụng để nhận giá trị tối đa của một đặc điểm đơn lẻ khi được áp dụng cho danh sách các loại.

template <template<class> class Trait, typename F, typename... T> 
struct trait_max 
    : std::integral_constant<decltype(Trait<F>::value), 
     (Trait<F>::value > trait_max<Trait, T...>::value) ? Trait<F>::value : trait_max<Trait, T...>::value> 
{ }; 
template <template<class> class Trait, typename F> 
struct trait_max<Trait, F> 
    : std::integral_constant<decltype(Trait<F>::value), Trait<F>::value> 
{ }; 

Đặc điểm này là thực sự hữu ích cho khi bạn cần biết tối đa của một tập hợp các loại như sau:

auto max_align = traits_max<std::alignment_of, int, float, std::string>::value; 
auto max_size = traits_max<std::size_of, int, float, std::string>::value; // doesn't exist 
+1

Lỗi trong mã của bạn, 'Trait 'phải là' Trait ' sau toán tử '?'. Tôi chỉ nhận thấy bởi vì điều này là tuyệt vời, và tôi đang sử dụng nó. –

+2

Lý do duy nhất 'std :: alignment_of ' là tiêu chuẩn vì nó là một phần của TR1. – Simple

+2

May mắn thay, 'mẫu struct size_of: std :: integral_constant {};' cũng không khó để viết. – Yakk

Trả lời

3

std::alignment_of không phải là mới trong C++ 11. Nó đã được bổ sung (cùng với phần còn lại của <type_traits>) như một phần của TR1 năm 2007. bán buôn <type_traits> đã được sao chép TR1 từ Boost TypeTraits, trong đó cung cấp alignment_of chỉ vì không có cách nào tiêu chuẩn để có được giá trị đó vào năm 2005.

Dĩ nhiên vào năm 2005, có một cách để có kích thước thuộc loại T; nó đã được viết chính tả sizeof(T) từ thời xa xưa. Đó là lý do tại sao size_of<T> không có trong Boost TypeTraits và đó là lý do tại sao nó không được sao chép vào TR1 trong năm 2007 và đó là tại sao nó không được đưa vào C++ 11.

Tính đến năm 2011, có cũng cách tiêu chuẩn để căn chỉnh loại T; nó được viết là alignof(T). Việc xây dựng trước năm 2011 std::alignment_of<T>::value là không cần thiết tiết, và bạn gần như chắc chắn không nên sử dụng nó nữa trừ khi bạn đang quan tâm về tính di động để triển khai trước năm 2011.

Tôi tin rằng cách thành ngữ nhất của việc viết mã mẫu của bạn là

size_t max_align = std::max({alignof(int), alignof(float), alignof(std::string)}); 
size_t max_size = std::max({sizeof(int), sizeof(float), sizeof(std::string)}); 

Khi C++ 14 cuộn xung quanh, std::max sẽ trở thành constexpr, vì vậy đây sẽ được tính tại thời gian biên dịch và được sử dụng trong mẫu metaprogramming. Nhưng sự hấp dẫn của C++ 11 std::max là một vấn đề hoàn toàn riêng biệt, không liên quan đến câu hỏi của bạn. :)

EDIT: Đây là constexpr_max hoạt động trong C++ 11 hiện tại. Rất tiếc, không thể sử dụng std::initializer_list của C++ 11 trong ngữ cảnh constexpr; C++ 14 cũng đang sửa lỗi đó.

template<typename T> constexpr T constexpr_max(T t, T u) { 
    return t > u ? t : u; 
} 

template<typename T, typename... TT> constexpr T constexpr_max(T t, TT... ts) { 
    return constexpr_max(t, constexpr_max(ts...)); 
} 
+0

Tôi đang sử dụng đặc điểm này trong lập trình meta mẫu, vì vậy các loại trong mã mẫu thường được dựng lên từ mẫu variadic. Tương tự như gợi ý của bạn, 'std :: max ({sizeof (T) ...});' sẽ là hoàn hảo, nhưng không có 'constexpr' trên' std :: max', tôi buộc phải dùng đến một đặc điểm tùy chỉnh. Tôi đoán tôi ngạc nhiên rằng điều này không xảy ra trong quá trình chuẩn hóa. Nếu 'alignment_of' được coi là vô ích trong một thế giới' alignof', tại sao không giảm giá trị nó? Nếu nó vẫn hữu ích, tại sao không thêm 'size_of' tương tự? Một trong những bí ẩn nhỏ của cuộc sống ... – marack

+0

Vâng, bạn buộc phải sử dụng một trong hai "đặc điểm tùy chỉnh" * hoặc * cho hàm 'max' tối đa tùy chỉnh, mà bạn đã thực sự đã viết, nếu bạn chỉ cần xóa' trait_' cruft từ 'trait_max' của bạn. :) Tôi sẽ cập nhật câu trả lời của tôi với mã mẫu. – Quuxplusone

+0

Rất đẹp. Cảm ơn! – marack

Các vấn đề liên quan