英文:
How can I avoid recompiling a specific template function each time I compile my project?
问题
我有一个名为foo.hpp
的文件,其中包含一个模板:
template<int a>
void foo()
{
// 复杂的函数
}
我在main.cpp
中使用它:
#include "foo.hpp"
int main()
{
// 快速编译的代码
// ...
foo<3>();
// 更多快速编译的代码
}
现在,每次我修改main.cpp
并重新编译项目时,需要重新编译foo<3>()
,尽管它没有更改。在我的情况下,绝大多数编译时间都花在重新编译foo<3>()
上,因此避免这种情况非常重要。
我想将项目分为两个步骤:
- 编译
foo<3>()
。这需要时间,但只需执行一次。 - 编译
main.cpp
。现在很快,因为foo<3>()
已经编译好了。
如何实现这种行为?我尝试在不同的文件中进行显式实例化,然后首先编译它,但main.cpp
的编译时间仍然相同。
感谢任何帮助!
编辑:
关于我尝试使用显式实例化的澄清:
创建一个新文件precompiled.cpp
:
#include "foo.hpp"
template void foo<3>();
然后尝试首先使用g++ -c precompiled.cpp
编译这个文件,之后使用g++ precompiled.o main.cpp
编译main.cpp
。但这会在步骤2中再次实例化foo<3>()
,我想避免这种情况。
英文:
Say I have a file foo.hpp
with a template
template<int a>
void foo()
{
// Complex function
}
which I use in my main.cpp
:
#include "foo.hpp"
int main()
{
// quickly compiled code
// ...
foo<3>();
// more quickly compiled code
}
Now each time I compile my project after changing main.cpp
, foo<3>()
needs to be compiled again, even though it doesn't change.
The vast majority of the compile time is spent compiling foo<3>()
in my case, so avoiding this is critical.
I would like to compile my project in two steps:
- Compile
foo<3>()
. This takes long but I only do it once. - Compile
main.cpp
. This is now fast becausefoo<3>()
is already compiled.
How can I achieve this behavior? I tried doing explicit instantiation in a different file and compiling this first, but main.cpp
still takes the same time to compile.
Thanks for any help!
EDIT:
Clarification of what I tried using explicit instantiation:
Create a new file precompiled.cpp
:
#include "foo.hpp"
template void foo<3>();
Then tried compiling this first with g++ -c precompiled.cpp
and afterwards, compile main.cpp
using g++ precompiled.o main.cpp
.
But this instantiates foo<3>()
again in step 2, which I want to avoid.
答案1
得分: 4
你在头文件中漏掉了extern template void foo<3>();
,这应该在foo
的定义之后。
英文:
You're missing extern template void foo<3>();
in the header, after the definition of foo
.
答案2
得分: 3
模板需要在头文件(`.hpp`)中定义,并在编译单元(`.cpp`)中实例化。与常规类不同,你不能在头文件中声明函数并在编译单元中定义它,否则会导致编译行为不符合预期:只有在实例化更改时才重新编译函数。
建议将对模板的所有调用包装在单独的 `.cpp` 文件中,并将这些调用包装在从 `main.cpp` 调用的函数中。这样,您可以修改 `main.cpp` 的其他部分而无需重新编译 `foo`。但是,如果您更改在另一个单元中使用它的方式,将重新编译 `foo`。
示例:
`foo3.cpp`:
```CPP
#include "foo.hpp"
void foo3() {
foo<3>();
}
foo3.hpp
:
#pragma once
void foo3();
main.cpp
:
#include "foo3.hpp"
int main()
{
// 快速编译的代码
// ...
foo3();
// 更多快速编译的代码
}
英文:
Templates need to be defined in headers (.hpp
) and instantiated in compilation units (.cpp
). Unlike regular classes, you cannot declare the function in a header and define it in a compilation unit, which would result in the compilation behaviour you expect: only recompile the function when it's instantiation changes.
I suggest wrapping all calls to your template in a separate .cpp
and wrap those calls in functions that will be called from main.cpp
. This way, you may modify other areas of main.cpp
without recompiling foo
. However foo
will be recompiled if you change how you use it in the other unit.
Example:
foo3.cpp
:
#include "foo.hpp"
void foo3() {
foo<3>();
}
foo3.hpp
:
#pragma once
void foo3();
main.cpp
:
#include "foo3.hpp"
int main()
{
// quickly compiled code
// ...
foo3();
// more quickly compiled code
}
答案3
得分: 2
你无法避免实例化 `foo<3>`,如果你正在使用一个函数。请使用以下替代:
```cpp
template<int a>
struct foo
{
void operator()() {
// 复杂的代码在这里
}
};
创建一个名为 bar.hpp
的文件,其中包含以下代码:
#include "foo.hpp"
struct foo_3 {
static foo<3> fooinst = foo<3>();
void operator()() {
foo_3::fooinst();
}
};
然后使用 bar.hpp
(你可以预编译它并生成 .gch
文件,尽管我对你坚持使用模板感到困惑。)
<details>
<summary>英文:</summary>
You cannot avoid instantiating `foo<3>` if you are using a function. Use this instead:
```cpp
template<int a>
struct foo
{
void operator()() {
//complex code here
}
};
Make a file say named bar.hpp
with the following code
#include "foo.hpp"
struct foo_3 {
static foo<3> fooinst = foo<3>();
void operator()() {
foo_3::fooinst();
}
};
And then use bar.hpp
(you are ALLOWED to precompile it returns a .gch
file. Though I'm puzzled why you insist using the template.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论