如何有“constexpr和运行时”别名 [英] How to have "constexpr and runtime" alias
问题描述
Constexpr对于编译优化可以是非常有用的。例如...
strlen(char *)
可以使用....预编译。
constexpr inline size_t strlen_constexpr char * baseChar){
return(
(baseChar [0] == 0)
?(// if {
0
)//}
:(// else {
strlen_constexpr(baseChar + 1)+ 1
)//}
);
}
其运行时成本为0 >当优化...但在运行时超过10 + x慢
//测试结果运行在2010 macbook空气
--------- strlen ---------
100,000次运行所需的时间:1054us。
平均运行时间:0.01054us。
--------- strlen_constexpr ---------
100,000次运行所花费的时间:19098us。
平均运行时间:0.19098us。
是否有任何现有的宏/模板黑客可以使用单个统一的函数。即
constexpr size_t strlen_smart(char * baseChar){
#if constexpr
... constexpr函数
#else其运行时
...运行时函数
}
$
constexpr size_t strlen_smart(char * baseChar){
.. 。constexpr function
}
inline size_t strlen_smart(char * baseChar){
...运行时函数
}
注意:此问题适用于一般概念。
免责声明:将编译器设置为-O3(优化级别)足以修复99.9%的静态字符优化,使所有上面的例子无意义。但这不是问题的重点,因为它适用于其他示例,而不只是 strlen
。我不知道任何通用的方法,但我知道两个具体的情况下是可能的。
编译器
同样gcc和clang复制gcc的所有特性,有一个内置函数 __ builtin_constant_p
。我不知道gcc是否会正确地看到参数的内联函数作为常量,但我担心你必须使用它从一个宏:
#define strlen_smart(s)\
(__builtin_constant_p(s)&& __builtin_constant_p(* s)?\
strlen_constexpr(s):\
strlen s))
可能有用。注意,我测试constexpr的 s
和 * s
,因为指向静态缓冲区
Bonus:文字的具体情况(不是真正的答案)
对于 所以你可以定义: 显然 我有时使用这种类型的参数的函数,即使在C ++ 98中,定义对应(我没有尝试重载 这有一个问题, 应该是0,但是优化的变体只是说9.这些函数没有意义调用像这样的缓冲区,所以我不在乎。 Constexpr can be awsome and useful for compilation optimisation. For example... Can be precompiled using.... Which gives it a runtime cost of "0" when optimised... But is more than 10+x slower on runtime Are there any existing macro / template hack where a single unified function can be used instead. ie. Or some overloading hack that would allow the following Note: This question applies to the concept in general. Of having 2 separate functions for runtime and constexpr instead of the example functions given. Disclaimer: Setting the compiler to -O3 (optimization level) is more than enough to fix 99.9% of static char optimizations making all the examples above "pointless". But that's beside the point of this question, as it applies to other "examples", and not just I don't know any generic way, but I know two specific cases where it is possible. Also gcc, and clang which copies all features of gcc, have a built-in function Might be of use. Note that I am testing both For the specific cast of So you can define: (plus obviously I've sometimes used function with this type of argument even in C++98 with definition corresponding to (I didn't try to overload This has the problem that for should say 0, but that optimized variant just says 9. The functions don't make sense to be called on buffers like that so I didn't care. 这篇关于如何有“constexpr和运行时”别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! strlen
的特定转换,您可以使用字符串字面值不是类型 const char *
但类型 const char [N]
隐式转换为 const char * / code>。但它也转换为
const char(&)[N]
以及 const char *
/ p>
template< size_t N>
constexpr size_t strlen_smart(const char(& array)[N])
strlen_smart
在 const char *
转发到 strlen
)
strlen
本身,但重载是所以我可以避免调用它):
template< size_t N> ;
size_t strlen_smart(const char(&)[N]){return N - 1; }
char buffer [10] = {0};
strlen_smart(buffer);
strlen(char*)
constexpr inline size_t strlen_constexpr(char* baseChar) {
return (
( baseChar[0] == 0 )
?(// if {
0
)// }
:(// else {
strlen_constexpr( baseChar+1 ) + 1
)// }
);
}
// Test results ran on a 2010 macbook air
--------- strlen ---------
Time took for 100,000 runs:1054us.
Avg Time took for 1 run: 0.01054us.
--------- strlen_constexpr ---------
Time took for 100,000 runs:19098us.
Avg Time took for 1 run: 0.19098us.
constexpr size_t strlen_smart(char* baseChar) {
#if constexpr
... constexpr function
#else its runtime
... runtime function
}
constexpr size_t strlen_smart(char* baseChar) {
... constexpr function
}
inline size_t strlen_smart(char* baseChar) {
... runtime function
}
strlen
.Specific case of some compilers
__builtin_constant_p
. I am not sure whether gcc will correctly see argument to inline function as constant, but I fear you'd have to use it from a macro:#define strlen_smart(s) \
(__builtin_constant_p(s) && __builtin_constant_p(*s) ? \
strlen_constexpr(s) : \
strlen(s))
s
and *s
for constexpr, because pointer to static buffer is a compile time constant while it's length is not.Bonus: Specific case of literals (not an actual answer)
strlen
you can use the fact that string literals are not of type const char *
but of type const char[N]
that implicitly converts to const char *
. But it also converts to const char (&)[N]
as well while const char *
does not.template <size_t N>
constexpr size_t strlen_smart(const char (&array)[N])
strlen_smart
on const char *
forwards to strlen
)strlen
itself, but the overloads were so I could avoid calling it):template <size_t N>
size_t strlen_smart(const char (&)[N]) { return N - 1; }
char buffer[10] = { 0 };
strlen_smart(buffer);