为什么我不能使用单个非类型参数内联模板函数的显式实例化?
Why can't I inline an explicit instantiation of a template function with a single non-type parameter?
假设我有一个在template.h
中声明并在template.cpp
中定义的非类型模板函数f(int)
(参数<int dim>
)。在template.cpp
中,我进一步为dim = 2
添加了一个专门化,然后显式实例化了dim = 1
和dim = 2
的模板函数。
文件编译得很好,但在链接过程中我遇到了一个错误:
Undefined symbols for architecture x86_64:
"void f<2>(int)", referenced from:
_main in main-2AW7ED.o
ld: symbol(s) not found for architecture x86_64
但是,如果我从模板专用化中删除inline
关键字(请参见下面的标记),那么整个过程将按预期进行。所以我的问题来了:
为什么inline
不适用于专用模板,而它适用于基本模板,而其他一切都可以编译并正常工作
main.cpp
#include <iostream>
#include "template.h"
using namespace std;
int main(int, char** )
{
f<1>(456);
f<2>(789);
}
template.h
template <int dim> void f(int src);
template.cpp
#include <iostream>
#include "template.h"
using namespace std;
template <int dim> inline
void f(int src)
{
cout << "src = " << src << endl;
cout << "dim (template) = " << dim << endl;
}
template <> inline // <== if I remove this "inline", everything works as expected
void f<2>(int src)
{
cout << "src = " << src << endl;
cout << "dim (fixed) = " << 2 << endl;
}
template void f<1>(int);
template void f<2>(int);
第页。S.:我使用g++和clang++与命令clang++ -o tmpl template.cpp main.cpp
进行编译。
如果函数被声明为inline
,编译器不必生成非内联版本,除非请求指向函数的指针,或者它决定在某个调用站点最好不要内联它(即使声明了inline
,编译器也不必总是内联)。
现在要内联函数,编译器需要在编译调用站点时查看函数的定义。但是您在.cpp
中定义了函数,并试图从不同的.cpp
调用它。因此,编译器不会看到定义,并尝试调用非内联版本。但它没有生成,因为你告诉编译器内联函数,它没有看到任何需要非内联版本的用途,所以它没有生成它。如果你没有声明inline
,那么默认值是extern
,并且总是生成非内联版本。并且您声明了要生成的显式实例,所以这些实例将是
正如编译器不必内联一样,它也不必生成外部版本。我怀疑存在一些随机差异,导致编译器在一种情况下生成非内联实例,而在另一种情况中不生成。在任何一种情况下,如果您以内联方式声明某个内容,则必须在标头中定义它,除非您实际上只从一个源使用它(例如,有时私有方法可以以内联方式在实现中定义,因为您只在该文件中使用它们)。
- 如何使用非默认构造函数实例化模板化类
- C++ - 使用另一个类的构造函数实例化一个对象
- 与参数匹配的友元模板函数实例化
- 在保证复制的世界中构造函数实例化
- SFINAE 和模板函数实例化:为什么在启用了 SFINAE 类型的函数参数中使用模板参数时无法推断模板参数?
- 防止复制构造函数实例化 C++11 类"deleting"
- 如何键入定义一个专门的 std::set 模板,使用特定的比较函数实例化
- 使用不同类型的模板函数实例化
- C 调用模板构造函数实例化
- 为什么很清楚模板函数实例化不会内联
- 模板函数实例化文件
- 模板函数实例化的可移植性问题
- 模板函数实例化 自定义数据类型的问题
- 模板类成员函数实例化
- C++.对象使用错误的构造函数实例化
- C++如何用参数化构造函数实例化对象
- 为什么无法使用复制构造函数实例化"non const"而可以在没有复制构造函数的情况下实例化配对?
- 双模板化函数实例化失败
- 延迟 crtp 基类中的成员函数实例化
- 如何根据容器的元素类型启用模板函数实例化