因爲在我工作的公司中禁止提升,所以我需要在純C++中實現它的功能。我已經研究過助推源,但他們似乎太複雜,至少對我來說是無法理解的。我知道在C++ 0x standart中有一個叫static_assert()
的東西,但我不想使用任何C++ 0x功能。BOOST_STATIC_ASSERT沒有提升
回答
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
int main() {
StaticAssert< (4>3) >(); //OK
StaticAssert< (2+2==5) >(); //ERROR
}
+1夠簡單,但我喜歡有一個與斷言相關的消息 – 2009-12-30 14:07:16
@Gregory:'StaticAssert < (2+2==5) > associatedMessage();' – 2009-12-30 17:19:01
有些地方你不想/不能使用變量雖然 – 2009-12-30 19:34:52
你可以從Boost source file宏簡單地複製到自己的代碼。如果您不需要支持Boost支持的所有編譯器,您可以爲編譯器選擇正確的定義,並省略該文件中其餘的#ifdef
。
這是合法的Boost的許可證嗎? – gatopeich 2011-06-07 17:41:05
其他一招(其可以在C中使用的)是試圖建立一個數組具有負的大小,如果斷言失敗:
#define ASSERT(cond) int foo[(cond) ? 1 : -1]
作爲獎勵,你可以使用一個typedef,而不是一個對象,因此,它在多個環境可用,並沒有發生,當它成功:
#define ASSERT(cond) typedef int foo[(cond) ? 1 : -1]
最後,建立一個名稱與名稱衝突的機會更少(和可重複使用至少在不同線路):
#define CAT_(a, b) a ## b
#define CAT(a, b) CAT_(a, b)
#define ASSERT(cond) typedef int CAT(AsSeRt, __LINE__)[(cond) ? 1 : -1]
有人可以解釋爲什麼兩個CAT宏是必要的嗎?你想避免什麼問題?謝謝。 – grokus 2010-12-16 20:24:50
如果你不這樣做,宏的參數(如'__LINE__')不會被擴展。所以它會生成'AsSeRt__LINE__'而不是想要的'AsSeRt42'。我很確定有一個問題在某處詳細解釋了這一點。 – AProgrammer 2010-12-17 14:58:37
我使用下面的頭文件,用代碼從別人撕開......
#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
這是我自己實現從我的代碼庫中提取靜態斷言的:Pre-C++11 Static Assertions Without Boost
。
用法:
STATIC_ASSERT(expression, message);
當靜態斷言測試失敗,則生成以某種方式包含STATIC_ASSERTION_FAILED_AT_LINE_xxx_message
一個編譯器的錯誤消息。
message
必須是一個有效的C++標識符,如no_you_cant_have_a_pony
這將產生含有編譯器錯誤:
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「no_you_cant_have_a_pony」 – 2009-12-31 02:45:49
非常好!這是一個完整的解決方案(如果你想避免自我提升,那麼這是一個很好的替代方案)+1 – Samaursa 2013-03-09 20:40:21
我認爲這應該工作:
template<bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert<true>{};
#define STATIC_ASSERT(e) (CompileTimeAssert <(e) != 0>())
- 1. BOOST_FOREACH沒有提升?
- 2. Asio沒有提升
- 3. CMake沒有找到提升
- 4. 項目建設有和沒有提升
- 5. 如何使用BOOST_STATIC_ASSERT
- 6. Parallel.ForEach和Regex沒有性能提升嗎?
- 7. gnuplot-iostream沒有鏈接到提升
- 8. 提升make_shared沒有模板參數
- 9. cmake沒有找到提升庫
- 10. boost ::線程沒有全部提升?
- 11. WampServer上的APC沒有性能提升
- 12. 爲什麼工具欄沒有提升?
- 13. enable_if +類型模板,沒有SFINAE(enable_if_c沒有提升?)
- 14. 哪個更好BOOST_MPL_ASSERT或BOOST_STATIC_ASSERT?
- 15. 使用存儲過程有沒有主要的性能提升?
- 16. 有沒有不需要提升的連接器/ C++庫?
- 17. C#TryParse有沒有提升lexical_cast等價物?
- 18. 用Webpack捆綁ES6類。有沒有辦法提升擴展類?
- 19. 有沒有辦法關閉提升日期和時間驗證
- 20. tortoiseSVN 1.8升級沒有升級svn.exe
- 21. 提升庫和持有值
- 22. BOOST_STATIC_ASSERT的名稱空間範圍
- 23. 升壓program_options沒有找到
- 24. 提升線程和提升Asio
- 25. 提升爲Android建設提升日誌
- 26. 索引時間文件提升沒有考慮到
- 27. OPcache計數緩存命中,但沒有性能提升
- 28. 如何(交叉)編譯提升沒有python?
- 29. 管道提升:: iostreams沒有任何輸出
- 30. 提升緩衝成char *(沒有的std :: string)
做你問爲什麼你不允許使用提升? – 2009-12-30 14:05:49
@Gregory Pakosz,他們說,因爲它太複雜了:) – Konstantin 2009-12-30 22:26:49