gpt4 book ai didi

c++ - 这个模板参数推导是如何工作的?

转载 作者:行者123 更新时间:2023-12-05 04:20:00 32 4
gpt4 key购买 nike

编译器如何在不知道 foo 函数的模板参数 T 类型的情况下决定调用 bar 函数?

通常当我们调用foo(2)时,T会根据参数2推导为int

这里的T是根据传递给foo的函数bar的参数推导出来的。

#include <iostream>

template<typename T>
void foo(const T& a_) {
std::cout << a_<< std::endl;
}

void bar(void (*ptr) (const int&)) {
std::cout << "bar called" << std::endl;
}

int main() {
bar(foo);
}

编译器:gcc

最佳答案

当你有一个像 foo 这样的重载集时,这意味着 foo 的名称查找结果会导致(可能是多个)非模板函数或函数模板,并且重载集有它的地址或引用(这里通过将其作为函数参数隐式传递),然后编译器将尝试对目标类型进行重载解析(如果有的话)。这里的目标类型是void(*)(const int&)。整个过程在 [over.over] 中指定。 ,我将在下面解释其中的部分内容。

它的工作方式是,编译器将查看重载集中的每个函数和函数模板,查看它是否可以将其类型与目标类型匹配,然后将那些匹配的函数和函数模板特化添加到一组选定的重载。之后再进行一些消除步骤以减少选定的重载集(例如,检查是否满足相关约束并优先选择函数而不是函数模板特化,请参阅 [over.over]/5 了解所有详细信息)并希望最后只选择一个函数或函数模板特化仍然存在,然后将选择它作为原始名称 (foo) 引用的重载解析的结果,并从中获取地址/引用。

对于非模板函数,匹配意味着目标的函数类型 (void(const int&)) 需要与函数的类型完全相同。但是这里没有任何非模板重载。

对于函数模板,编译器将尝试执行模板参数推导以选择与类型匹配的模板特化,并且可以将其添加到所选重载列表中。具体来说,这与函数调用的模板参数推导相同,其中通常有一个函数参数/参数对列表来推导模板参数,但在这种情况下(假设有目标类型)推导将考虑只有一个参数/参数对,参数是目标类型 (void(*)(const int&)),参数是包含模板参数的模板的函数类型,即这里的 void(const T&),调整为指针类型void(*)(const T&),因为参数是函数指针类型。

所以最后编译器会进行正常的推导

void(*)(const int&)

反对

void(*)(const T&)

决定什么T应该在选定的特化。我想很明显 T 应该是 int 才能匹配类型。因此,选定的特化将是具有 T = int 的特化,它具有与目标类型匹配的函数类型,并且因为它是唯一选定的重载并且因为它不会在任何进一步的步骤中被消除,它将被选择为重载决议的结果。

关于c++ - 这个模板参数推导是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74602934/

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