C++;编译时连续内联 我尝试在下面的C++代码中嵌入: __attribute__((always_inline)) static void inline compose(const char* s, std::function<void(const char *)> f) { std::cout << s << std::endl; f(s); } // --------------- Main --------------- int main() { // Nest three things compose("hello world", [](const char *s) { compose("hello again", [](const char *s) { compose("hello third time", [](const char *s) { return; }); }); }); return 0; }
是否可以在编译时执行此操作?我认为编译器不能自动完成这项工作,但我认为预处理器可能会使用constexpr和C++17。Clang对其进行了很好的优化。使用C++;编译时连续内联 我尝试在下面的C++代码中嵌入: __attribute__((always_inline)) static void inline compose(const char* s, std::function<void(const char *)> f) { std::cout << s << std::endl; f(s); } // --------------- Main --------------- int main() { // Nest three things compose("hello world", [](const char *s) { compose("hello again", [](const char *s) { compose("hello third time", [](const char *s) { return; }); }); }); return 0; },c++,C++,是否可以在编译时执行此操作?我认为编译器不能自动完成这项工作,但我认为预处理器可能会使用constexpr和C++17。Clang对其进行了很好的优化。使用std::function只会产生与类型擦除相关的少量开销: 延续样式: 直接风格: 我使用了一个dummy_write()来避免使用iostream和std::cout生成的外观复杂的程序集 通过模板化compose而不是使用std::function,可以消除这种类型的擦除: 模板 __属性_uuu((始终_内联)) 静态void内联合成
std::function
只会产生与类型擦除相关的少量开销:
延续样式:
直接风格:
我使用了一个dummy_write()
来避免使用iostream
和std::cout
生成的外观复杂的程序集
通过模板化compose
而不是使用std::function
,可以消除这种类型的擦除:
模板
__属性_uuu((始终_内联))
静态void内联合成(常量字符*s,函数f){
伪写;
f(s);
}
将compose标记为constexpr,这显然是不起作用的解决方案,我尝试将constexpr添加到lambdas中,但没有效果。您怎么知道编译器无法自动优化延续代码,使其性能与第二个版本相当?你试过godbolt吗?我用llvm,我只是观察了IR。我不熟悉godbolt。这是模板的一个很好的用途,谢谢!奇怪的是,为什么在延续样式程序集中有四个对dummy_write的调用?第四个dummy_write
似乎是与std::function
实现关联的\M_invoke()
方法的一部分。它实际上没有在main()
中调用,但没有优化。如果未优化使用std::function
,则可能会调用\u M_invoke()
。感谢ls的进一步解释!
// --------------- Main ---------------
int main() {
// Nest three things
std::cout << "hello world" << std::endl;
std::cout << "hello again" << std::endl;
std::cout << "hello third time" << std::endl;
return 0;
}
template<typename Func>
__attribute__((always_inline))
static void inline compose(const char* s, Func f) {
dummy_write(s);
f(s);
}