如果我转发声明一个函数模板,我可以将定义放在调用站点之后而不显式实例化它吗?

If I forward declare a function template, may I put the definition after the calling site and not explicit instantiate it at all?

提问人:zwhconst 提问时间:8/15/2023 最后编辑:zwhconst 更新时间:8/15/2023 访问量:76

问:

在一个大型项目的头文件中,我必须在调用站点之前转发声明一个函数模板。代码可以归结为:

//H1.h

#pragma once

template <typename>
void f();

inline void g()
{
    f<void>();
}
//POI #1

template <typename>
void f()
{}
//TU1.cpp

#include "H1.h"

void func1()
{
    g();
}

//(End of TU) POI #2
//TU2.cpp

#include "H1.h"

void func2()
{
    g();
}

//(End of TU) POI #3

据我了解,#1、#2 和 #3 是 .在 POI #1 中,尚未定义。在定义 之后,就没有显式的实例化来告诉编译器具体实例化。编译器是否记得在 TU 末尾生成代码?测试结果是肯定的,至少在使用 GCC、clang 或 MSVC 时是这样。ffff<void>f<void>

但问题是:函数模板的这种声明-调用-定义模式是否符合标准?

我不是标准的专家,但我搜索了标准文本以查找相关单词,并且仅在使用显式实例化时才找到此规则。但我不确定模板是隐式实例化的情况。

C++ 语言 - 律师 forward-declaration 函数 templates

评论

0赞 Öö Tiib 8/15/2023
为什么要把两个问题结合起来?我投票决定关闭焦点。是的,它是犹太洁食,见 stackoverflow.com/questions/7255281/...模板和内联不受 ODR 的影响,除非您真正将它们定义为在不同的翻译单元中发生冲突。
0赞 zwhconst 8/15/2023
@ÖöTiib 谢谢你的提示。我删除了问题 2。
0赞 Öö Tiib 8/15/2023
好的,我撤回投票。
0赞 Language Lawyer 8/15/2023
模板实例化阶段遵循语法和语义分析阶段,因此这看起来可以在模板定义首次“使用”之后找到它。timsong-cpp.github.io/cppwp/n4868/lex.phases#1.7.sentence-3 timsong-cpp.github.io/cppwp/n4868/lex.phases#1.8
1赞 Language Lawyer 8/15/2023
另请参阅 timsong-cpp.github.io/cppwp/n4659/temp#7

答: 暂无答案