2012-10-01 32 views

Trả lời

13
unsigned myFunction() {return 0;} 

template <typename Head, typename... Tail> 
unsigned myFunction(const Head & head, const Tail &... tail) { 
    return sizeof head + myFunction(tail...); 
} 
+0

Thông minh (+1) - với 'nội tuyến' sẽ còn thông minh hơn. – PiotrNycz

+2

@PiotrNycz: 'inline' như một điều tối ưu hóa, chỉ là một gợi ý. Chỉ có bấy nhiêu thôi. Cá nhân tôi giá trị mã rõ ràng hơn nhiều so với gợi ý đó, và sau đó 'inline' tốt hơn nên được dành riêng cho một hiệu ứng đảm bảo của nó, cụ thể là hiệu ứng ODR của nó. –

+7

@PiotrNycz: Có, nếu bạn cần xác định quá tải không phải mẫu trong một tệp tiêu đề, thì nó sẽ cần phải là 'inline'. Đó là khá không liên quan đến câu hỏi, mặc dù. –

4

Dựa tắt của this comment và các ý kiến ​​sau đây về vấn đề, bạn có thể sử dụng này (lưu ý: hoàn toàn chưa được kiểm tra)

std::initializer_list<std::size_t> sizeList = {sizeof(List)...}; //sizeList should be std::initializer_list, according to the comments I linked to 
return std::accumulate(sizeList.begin(), sizeList.end(), 0); 
+0

Điều này đặt ra câu hỏi thú vị: điều này sẽ được tính toán tĩnh (tất cả các con đường xuống)? –

+0

Tôi không nghĩ rằng điều này sẽ được tính toán tĩnh trừ khi ai đó tạo một phiên bản std :: tích lũy, hoặc nếu bạn có trình biên dịch siêu tối ưu, nhưng tôi không biết liệu trình biên dịch có tối ưu hóa nhiều không. – JKor

+0

tiếc là tôi không có một phiên bản của Clang với 'std :: initializer_list':/ –

-2

Tôi vừa mới phát hiện ra rằng:

template<typename... List> 
inline unsigned int myFunction(const List&... list) 
{ 
    return sizeof(std::make_tuple(list...)); 
} 

Nhưng:

1) Tôi có đảm bảo rằng kết quả sẽ luôn giống nhau trên tất cả các trình biên dịch không?

2) Do make_tuple sẽ tạo và nạp tiền ở thời gian biên dịch?

+2

Điều này không tính toán tổng kích cỡ. Bạn có một đảm bảo rằng kích thước của tuple lớn hơn hoặc bằng tổng của các kích thước. –

+0

Làm thế nào nó có thể lớn hơn? – Vincent

+1

Việc triển khai được phép thực hiện những gì họ muốn. Có lẽ thực tế hơn, hãy nhớ rằng sự đảm bảo duy nhất về kích thước của một cái gì đó như 'struct {int i; đôi j; }; 'là ít nhất là' sizeof (int) + sizeof (double) ', nhưng nó có thể lớn hơn. –

2

Hai năm cuối nhưng một giải pháp thay thế đảm bảo được tính bởi trình biên dịch (nếu bạn không nhớ các cú pháp khác nhau):

template < typename ... Types > 
struct SizeOf; 

template < typename TFirst > 
struct SizeOf <TFirst> 
{ 
    static const auto Value = (sizeof(TFirst)); 
}; 

template < typename TFirst, typename ... TRemaining > 
struct SizeOf < TFirst, TRemaining ... > 
{ 
    static const auto Value = (sizeof(TFirst) + SizeOf<TRemaining...>::Value); 
}; 

Được sử dụng như const int size = SizeOf<int, char, double>::Value; // 4 + 1 + 8 = 13

5

Trong C++ 17, sử dụng một biểu lần:

template<typename... List> 
inline constexpr unsigned int myFunction(const List&... list) 
{ 
    return (0 + ... + sizeof(List)); 
} 
0

Dưới đây là một mẫu cách:

#include <iostream> 

template<typename T, typename ...Ts> 
class PPackSizeOf 
{ 
    public: 
    static const unsigned int size = sizeof(T) + PPackSizeOf<Ts...>::size; 
}; 


template<typename T> 
class PPackSizeOf<T> 
{ 
    public: 
    static const unsigned int size = sizeof(T); 
}; 

template<typename ...Ts> 
class FixedSizeBlock 
{ 
    private: 
     char block[PPackSizeOf<Ts...>::size]; 
    public: 

}; 

int main() 
{ 
    FixedSizeBlock<char,long> b; 
    std::cout << sizeof(b) << std::endl; 
    return 0; 
} 
Các vấn đề liên quan