Kể từ khi tăng bị cấm trong một công ty tôi làm việc cho tôi cần phải thực hiện chức năng của nó trong C++ tinh khiết. Tôi đã xem xét các nguồn tăng nhưng dường như chúng quá phức tạp để hiểu, ít nhất là đối với tôi. Tôi biết có cái gì đó gọi là static_assert()
trong standart C++ 0x, nhưng tôi không muốn sử dụng bất kỳ tính năng C++ 0x nào.BOOST_STATIC_ASSERT mà không cần tăng cường
Trả lời
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
int main() {
StaticAssert< (4>3) >(); //OK
StaticAssert< (2+2==5) >(); //ERROR
}
+1 đơn giản, nhưng tôi muốn có một thông báo liên quan đến xác nhận –
@Gregory: 'StaticAssert < (2+2==5) > associatedMessage();' –
có những nơi bạn không muốn/không thể sử dụng biến mặc dù –
Bạn chỉ cần sao chép macro từ Boost source file vào mã của riêng bạn. Nếu bạn không cần hỗ trợ tất cả các trình biên dịch, Boost hỗ trợ bạn có thể chọn đúng định nghĩa cho trình biên dịch của bạn và bỏ qua phần còn lại của tệp #ifdef
trong tệp đó.
Điều đó có hợp pháp với giấy phép của Boost không? – gatopeich
Một mẹo nhỏ khác (có thể được sử dụng trong C) là cố gắng xây dựng một mảng với kích thước tiêu cực nếu khẳng định thất bại:
#define ASSERT(cond) int foo[(cond) ? 1 : -1]
như một phần thưởng, bạn có thể sử dụng một typedef thay vì một đối tượng, do đó nó là có thể sử dụng trong nhiều bối cảnh và không xảy ra khi nó thành công:
#define ASSERT(cond) typedef int foo[(cond) ? 1 : -1]
cuối cùng, xây dựng một tên có ít cơ hội của tên đụng độ (và tái sử dụng ít nhất là trong dòng khác nhau):
#define CAT_(a, b) a ## b
#define CAT(a, b) CAT_(a, b)
#define ASSERT(cond) typedef int CAT(AsSeRt, __LINE__)[(cond) ? 1 : -1]
Ai đó có thể giải thích tại sao hai macro CAT là cần thiết? Bạn đang cố tránh vấn đề gì? Cảm ơn. – grokus
Nếu bạn không làm điều đó, các đối số là các macro (như '__LINE__') không được mở rộng. Vì vậy, nó sẽ tạo ra 'AsSeRt__LINE__' thay vì muốn 'AsSeRt42'. Tôi khá chắc chắn có một câu hỏi ở đâu đó giải thích chi tiết này. – AProgrammer
Tôi đang sử dụng tập tin tiêu đề sau đây, với mã tách từ người khác ...
#ifndef STATIC_ASSERT__H
#define STATIC_ASSERT__H
/* ripped from http://www.pixelbeat.org/programming/gcc/static_assert.html */
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
/* These can't be used after statements in c89. */
#ifdef __COUNTER__
/* microsoft */
#define STATIC_ASSERT(e) enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }
#else
/* This can't be used twice on the same line so ensure if using in headers
* that the headers are not included twice (by wrapping in #ifndef...#endif)
* Note it doesn't cause an issue when used on same line of separate modules
* compiled with gcc -combine -fwhole-program. */
#define STATIC_ASSERT(e) enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
#endif
/* http://msdn.microsoft.com/en-us/library/ms679289(VS.85).aspx */
#ifndef C_ASSERT
#define C_ASSERT(e) STATIC_ASSERT(e)
#endif
#endif
Đây là thực hiện riêng của tôi về khẳng định tĩnh chiết xuất từ cơ sở mã của tôi: Pre-C++11 Static Assertions Without Boost
.
Cách sử dụng:
STATIC_ASSERT(expression, message);
Khi thử nghiệm khẳng định tĩnh thất bại, một thông báo lỗi biên dịch rằng bằng cách nào đó có chứa các STATIC_ASSERTION_FAILED_AT_LINE_xxx_message
được tạo ra.
message
có phải là một C++ định danh hợp lệ, như no_you_cant_have_a_pony
mà sẽ tạo ra một lỗi biên dịch có chứa:
STATIC_ASSERTION_FAILED_AT_LINE_1337_no_you_cant_have_a_pony
:)
#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2)
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2)
#define CONCATENATE2(arg1, arg2) arg1##arg2
/**
* Usage:
*
* <code>STATIC_ASSERT(expression, message)</code>
*
* When the static assertion test fails, a compiler error message that somehow
* contains the "STATIC_ASSERTION_FAILED_AT_LINE_xxx_message" is generated.
*
* /!\ message has to be a valid C++ identifier, that is to say it must not
* contain space characters, cannot start with a digit, etc.
*
* STATIC_ASSERT(true, this_message_will_never_be_displayed);
*/
#define STATIC_ASSERT(expression, message)\
struct CONCATENATE(__static_assertion_at_line_, __LINE__)\
{\
implementation::StaticAssertion<static_cast<bool>((expression))> CONCATENATE(CONCATENATE(CONCATENATE(STATIC_ASSERTION_FAILED_AT_LINE_, __LINE__), _), message);\
};\
typedef implementation::StaticAssertionTest<sizeof(CONCATENATE(__static_assertion_at_line_, __LINE__))> CONCATENATE(__static_assertion_test_at_line_, __LINE__)
// note that we wrap the non existing type inside a struct to avoid warning
// messages about unused variables when static assertions are used at function
// scope
// the use of sizeof makes sure the assertion error is not ignored by SFINAE
namespace implementation {
template <bool>
struct StaticAssertion;
template <>
struct StaticAssertion<true>
{
}; // StaticAssertion<true>
template<int i>
struct StaticAssertionTest
{
}; // StaticAssertionTest<int>
} // namespace implementation
STATIC_ASSERT(true, ok);
STATIC_ASSERT(false, ko);
int main()
{
return 0;
}
+1 cho "no_you_cant_have_a_pony" –
Rất đẹp! Đây là một giải pháp hoàn chỉnh (và là một giải pháp thay thế tốt để tăng cường triển khai nếu bạn muốn tránh tăng cường chính nó) +1 – Samaursa
Tôi tin rằng điều này sẽ làm việc:
template<bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert<true>{};
#define STATIC_ASSERT(e) (CompileTimeAssert <(e) != 0>())
- 1. Chức năng TimerCallback dựa trên mẫu tiêu chuẩn LIbrary mà không cần tăng cường
- 2. Có thể sử dụng thực tế tăng cường trong nhà mà không cần GPS
- 3. Có Thư viện tăng cường gui không?
- 4. Tăng cường việc sử dụng
- 5. Cách tắt tăng cường EBean
- 6. Cách đặt checkbox.isChecked mà không cần tăng sự kiện
- 7. Tăng cường GA của tôi với các mạng nơron và/hoặc tăng cường học tập
- 8. Tăng cường linker lỗi Visual C++
- 9. Thực hiện tốt việc học tăng cường?
- 10. cmake không tìm thấy thư viện tăng cường
- 11. cách tăng cường multi_index được thực hiện
- 12. Jinja2, Backbone.js và tăng cường tiến bộ
- 13. Tại sao không có tăng cường :: filesystem :: move_file?
- 14. Trong mô-đun BillingService, những gì cần phải được sửa đổi để tăng cường bảo mật?
- 15. Tăng cường triển khai Mutex cho Windows
- 16. Tham chiếu mã lỗi tăng cường
- 17. Tăng cường là gì :: program_options :: notify() cho?
- 18. tạo công cụ tăng cường thực thi
- 19. Danh sách tăng cường xâm nhập móc
- 20. Python tăng cường phân công vấn đề
- 21. Tăng cường tinh thần QI chậm
- 22. tập tin nhật ký tăng cường không được ghi vào
- 23. Eclipse Google -App -Engine "sẽ không tăng cường"
- 24. Tăng cường nhật ký severity_logger init_from_stream
- 25. Java tăng cường cho vòng lặp VS .NET foreach loop
- 26. Sử dụng thử nghiệm tăng cường với Visual Studio
- 27. Được tăng cường :: luồng xử lý liên tục?
- 28. Ống kính Windows Phone 8 tăng cường thực tế
- 29. Lắng nghe phát sóng udp với thư viện tăng cường
- 30. Tăng cường phương pháp xác định trước trong Scala
làm bạn hỏi tại sao bạn không được phép sử dụng tăng? –
Không ai chịu nỗi đau khi xây dựng vụ án để nhóm luật sư chấp thuận việc sử dụng nó? – AProgrammer
@Gregory Pakosz, họ nói bởi vì nó quá phức tạp :) – Konstantin