gpt4 book ai didi

c++ - 编译器如何决定调用哪个函数模板?

转载 作者:行者123 更新时间:2023-12-01 15:12:51 25 4
gpt4 key购买 nike

当重载两个函数模板时,编译器如何决定调用哪个函数:

#include <iostream>
#include <typeinfo>

#ifndef B1
template <typename T1, typename T2>
auto max(T1 a, T2 b) {
std::cout << "auto version called" << std::endl;
return b < a ? a : b;
}
#endif

#ifndef B2
template <typename RT, typename T1, typename T2>
RT max(T1 a, T2 b) {
std::cout << "RT version called" << std::endl;
return b < a ? a : b;
}
#endif

template <typename T>
void print(T t) {
std::cout << typeid(t).name() << std::endl;
}

int main() {
auto b = ::max<long double>(4, 7.2);
print(b);

auto c = ::max<int>(4, 7.2);
print(c);

auto d = ::max<double>(4, 7.2);
print(d);

return 0;
}

我用命令构建了代码:

$ g++ -o m1 ./maxdefault4.cpp  -std=c++14  -DB1
$ g++ -o m2 ./maxdefault4.cpp -std=c++14 -DB2

意思是两个函数模板都可以匹配,但是为什么没有歧义错误造成。如果使用命令构建:

$ g++ -o m ./maxdefault4.cpp  -std=c++14 

编译器告诉我错误:

error: call to 'max' is ambiguous
auto c = ::max<int>(4, 7.2);

最佳答案

I built the code with command:

$ g++ -o m1 ./maxdefault4.cpp -std=c++14 -DB1

$ g++ -o m2 ./maxdefault4.cpp -std=c++14 -DB2

It means that both two function template can match, but why no ambiguity error caused.

这不对:当你传递-DB1-DB2时,你只编译了一个模板,所以没有歧义的问题,而且不是令人惊讶的是它可以编译。

And if buid with command:

$ g++ -o m ./maxdefault4.cpp -std=c++14

the compiler show me the error: ...

当你编译两个模板时会发生这种情况,并且更有趣,因为有些调用编译,但其他调用不编译。

要了解发生了什么,让我们看看当您拥有以下模板时会发生什么:

template <typename T1, typename T2> 
auto max(T1 a, T2 b); // #1

template <typename RT, typename T1, typename T2>
RT max(T1 a, T2 b); // #2

然后你打电话:

max<double>(4, 7.2);

这里,编译器将替换提供的参数double,并从参数中推导出剩余的模板参数。

这会产生:

template<>
double max<double, double>(double a, double b); // #1' from #1
// T1 = double (explicitly specified for 1st template parameter)
// T2 = double (deduced from 2nd function argument)

template<>
double max<double, int, double>(int a, double b); // #2' from #2
// RT = double (explicitly specified for 1st template parameter)
// T1 = int (deduced from 1st function argument)
// T2 = double (deduced from 2nd function argument)

现在使用重载解析来确定 #2' 更适合参数 47.2,所以 #2' 被调用。

同样,对于这个调用:

max<int>(4, 7.2);

编译器将替换提供的参数int,并从参数中推导出剩余的模板参数。

这会产生:

template<>
double max<int, double>(int a, double b); // #1' from #1
// T1 = int (explicitly specified for 1st template parameter)
// T2 = double (deduced from 2nd function argument)

template<>
int max<int, int, double>(int a, double b); // #2' from #2
// RT = int (explicitly specified for 1st template parameter)
// T1 = int (deduced from 1st function argument)
// T2 = double (deduced from 2nd function argument)

现在使用重载解析,但 #1'#2' 之间存在歧义,因为两者都没有比另一个更好的匹配(请注意返回类型在重载决议中不起任何作用)。这会导致您观察到的错误。

关于c++ - 编译器如何决定调用哪个函数模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62362365/

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