gpt4 book ai didi

c++ - 避免多次编译内联函数的定义

转载 作者:行者123 更新时间:2023-12-05 04:30:09 25 4
gpt4 key购买 nike

我在头文件中有一个非模板结构:

struct X {
constexpr X() : /* ... */ { /* ... */ }
constexpr void f() {
// ...
}
};

具有不同大小的函数。这用于许多不同的翻译单元,并且每个函数出现在多个目标文件中,以便它们在最终的可执行文件中被丢弃。

我想要的是将定义放在单个目标文件中,而其他翻译单元可以内联函数或使用外部定义(类似于 C 中的 extern inline 语义) .我该怎么做?

它似乎适用于模板和extern template:

namespace detail {

template<std::nullptr_t>
struct X_base {
constexpr X_base() // ...
constexpr void f() // ...
};

extern template struct X_base<nullptr>;

}

struct X : detail::X_base<nullptr> {
using X_base::X_base;
};

// X.cpp
#include <X.hpp>

template struct detail::X_base<nullptr>;

但这是否有任何重大缺点(符号名称较长、难以阅读、需要文档等),或者是否有更简单的方法来做到这一点?

最佳答案

C++ 没有内联函数的概念,它必须在一个翻译单元中发出,因此肯定不需要在其他任何地方发出。 (它根本没有发出目标代码的概念,但关键是没有语法说“我保证这个定义与其他定义是 ODR 相同的,除了它而且只有它带有这个标记。”所以编译器可以做到这一点。)

但是,您想要的行为是实现 C++20 模块的明显方式:因为已知模块中内联函数的定义是唯一的定义,它可以而且应该发出一次,以防多个导入翻译单元需要它的外联拷贝。 (内联仍然是可能的,因为作为构建模块的一部分,定义在编译器内部形式中可用。)请记住,在模块的类中定义的成员函数不会自动内联,尽管 constexpr 仍然暗示它。

另一个丑陋的解决方法是使非内联包装器在不断评估之外使用,尽管如果有多个级别的 constexpr 函数也可能在运行时使用,这可能会变得笨拙。

关于c++ - 避免多次编译内联函数的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72125663/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com