编译器如何重载模板函数而不改变参数列表
How compiler overloades template function without argument list change?
如下面的代码所示,方法get
被模板化了。
struct A
{
int i;
char c;
};
class SL
{
static void* m_a;
public:
template <class T>
static T* get()
{
return static_cast<T*>(m_a);
}
};
void* SL::m_a = new A{12, 'C'};
int main()
{
std::cout << SL::get<A>()->i;
return 0;
}
我不明白的是,当我写SL::get<B>()
时,编译器如何创建两个具有相同名称的方法,在同一名称空间中,具有两种不同的返回类型,两者都没有参数,即没有不同的参数列表?他们是如何让彼此超负荷的?或者理解庙函数生成具有相同的名称并通过重载解析解释它们的调用是错误的?
模板实例实际上是不重载的不同的函数。您可以将模板参数<B>
视为函数名的一部分。因此,SL::get<A>
和SL::get<B>
实际上是不同的函数(尽管源于相同的模板)。
引用cppreference:
模板实参推导发生在函数模板名查找之后(可能涉及与实参相关的查找)和重载解析之前。
如你所见,重载解析是一个不同的过程。
这是编译器特有的,你不应该太担心。这是如何实现的一个总体思路:
假设你用两个不同的类型调用模板化方法
SL::get<A>();
SL::get<B>();
编译器为这些调用生成两个新方法:
static A* get_a()
{
// etc..
}
和
static B* get_b()
{
// etc..
}
这可能因编译器而异,但它显示了编译器如何避免名称冲突。对于程序员来说,这是同一个方法被调用两次,对于编译器来说,这只是两个不同的方法被不同的代码调用。
模板很容易像其他东西一样命名混淆。当生成确切的get
时,它实际上不再称为get
,而是称为get@YUQIE
或类似的名称。您可以查看本文中的示例。这是实现定义的,所以不同的编译器会以不同的方式来做。例如,在以下代码
template <class T>
T get()
{
return T();
}
int main()
{
get<int>();
get<char>();
return 0;
}
get
被gcc修改为get<int>
的_Z3getIiEPT_v
和get<char>
的_Z3getIcEPT_v
。
相关文章:
- 变量没有改变?通过向量的函数调用
- 为什么提升图库的 read_graphviz() 函数会改变节点的索引
- 为什么我的函数接受"std::string"进行排序不会改变它?
- 通过从构造函数中的'this'复制的指针改变常量对象
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 有没有办法创建一个不改变程序中参数的函数
- 为什么我的函数不改变对象的属性
- 类中的枚举在调用自己的函数时不会改变
- C - 如何将各处的静态函数称为改变其私有变量
- 基于继承的类型参数改变父虚拟函数的行为
- 对列表中的每个对象调用成员函数,以改变对象所在的列表
- 为什么调用 CUDA 内核函数时这个类成员变量没有改变
- 当函数应该改变对象的状态时,是选择成员函数还是朋友函数
- 一个什么都不做的函数可以改变一个对象吗?
- ifstream 函数"get"如何改变其字符参数?
- 为什么一个函数的末尾有常量这个词,即使它确实改变了一个变量
- visual C++未执行的代码会改变函数行为
- 不被类函数改变的私有int值
- 谷歌模拟函数改变参数值
- 被非const成员函数改变的可变变量