- 论坛徽章:
- 2
|
本帖最后由 OwnWaterloo 于 2012-05-03 19:15 编辑
AD8018 发表于 2012-05-03 18:29 ![]()
2. typedef int check_succ[f("101")]; typedef int check_fail[f("12")];
试过了,gcc 4.6.2下,编译没有报错。
编译器版本:
- gcc --version
- gcc (GCC) 4.6.2
复制代码 代码:
- #include <assert.h>
- constexpr int f(char const* s, int acc=0)
- {
- return *s == 0
- ? acc
- : *s == '0' || *s == '1'
- ? f(s+1, *s-'0' + (acc << 1))
- : (assert(!"invalid digits"), -1);
- }
- typedef int array_success[f("10")];
- #ifdef ARRAY
- typedef int array_failure[f("12")];
- #endif
- enum {
- enum_success = f("10"),
- #ifdef ENUM
- enum_failure = f("12"),
- #endif
- };
- #ifdef NON_TYPE
- template<int> struct message {};
- message<f("10")> success;
- message<f("12")> faiture;
- #endif
- #ifdef CONST
- int const const_success = f("10");
- int const const_failure = f("12");
- #endif
复制代码 里面包含了一些常见的编译时技术计算所使用的构造。
如果将f("12")用作数组维度会报错:
- gcc -c -Wall -x c++ -std=c++0x -DARRAY
- error: size of array 'array_failure' is not an integral constant-expression
复制代码 而f("10")没问题。
如果将f("12")用作enum会报错:
- gcc -c -Wall -x c++ -std=c++0x -DENUM
- in constexpr expansion of 'f(((const char*)"12"), 0)'
- in constexpr expansion of 'f((s + 1u), ((((int)(* s)) + -0x000000030) + (acc << 1)))'
- error: 'void _assert(const char*, const char*, int)' is not a constexpr function
- error: enumerator value for 'enum_failure' is not an integer constant
复制代码 注意"_assert ... is not a constexpr function"。
而f("10") 没问题
如果将f("12")用作non-type参数会报错:
- gcc -c -Wall -x c++ -std=c++0x -DNON_TYPE
- in constexpr expansion of 'f(((const char*)"12"), 0)'
- in constexpr expansion of 'f((s + 1u), ((((int)(* s)) + -0x000000030) + (acc << 1)))'
- error: 'void _assert(const char*, const char*, int)' is not a constexpr function
- ...
复制代码 而f("10")没问题
而const比较麻烦,因为它并不向上面那几个,只能接受常量表达式。它的初始化可以接受非常量表达式。
- gcc -c -Wall -x c++ -std=c++0x -DCONST
- nm
- 00000000 t __Z41__static_initialization_and_destruction_0ii
- 00000000 b __ZL13const_failure
- 0000001c r __ZL13const_success
复制代码 const_success分配在rdata,可知它的值在编译时就已知了。
const_failure分配在bss,会被static_initialization_and_destruction在运行时初始化。
AD8018 发表于 2012-05-03 18:29 ![]()
1. 有意义的
实现 user-defined literals啊
"constexpr可接受运行时参数,整个表达式在运行时求值",这同样可以实现user-defined literal。并不矛盾。
|
|