gpt4 book ai didi

c++ - 函数模板 - 编译器在使用相同类型调用时选择具有不同参数类型的函数

转载 作者:太空狗 更新时间:2023-10-29 20:53:08 24 4
gpt4 key购买 nike

我在玩函数模板时偶然发现了一个奇怪的交互。

template<class T1, class T2>
void foo(T1, T1);

template<class T1, class T2>
void foo(T1, T2);

//main
foo(1,1)

这会调用 foo(T1, T2),但我不明白为什么。那将如何工作?这些函数是否相互重载,为什么编译器会选择具有不同参数类型的函数?

在 Henri Menke 的帖子的第一部分中解释了这种特殊的交互


经过一番摸索,我发现了一些奇怪的东西

#include <iostream>

template<class T1, class T2>
void foo(T1 a, T1 b)
{
std::cout << "same\n";
}

template<class T1, class T2>
void foo(T1 a, T2 b)
{
std::cout << "different\n";
}

int main()
{
foo(1, 1);
foo<int, int>(1, 1);
}

在这段代码中我得到了一个结果

different
different

但是在像这样注释掉第一个电话之后

int main()
{
//foo(1, 1);
foo<int, int>(1, 1);
}

结果是

same

我正在使用 VS2015,如果我在 Ideone ( like here ) 中写同样的东西,第一个的结果是

different
same

有人可以解释发生了什么(或没有发生什么)吗?


顺便说一句,我得出的结论是调用foo<int, int>(1, 1);应该是模棱两可的。两个函数模板具有相同的签名,并且来自相同的模板。所以那是另一回事,为什么它们不发生碰撞?

最佳答案

通过简单地删除第二个模板很容易看出失败的原因,即有一个像

这样的源文件
template<class T1, class T2>
void foo(T1, T1);

int main()
{
foo(1,1);
}

这在 Clang 中失败并出现错误

test.cpp:6:3: error: no matching function for call to 'foo'
foo(1,1);
^~~
test.cpp:2:6: note: candidate template ignored: couldn't infer template argument
'T2'
void foo(T1, T1);
^
1 error generated.

编译器无法推导出第二个模板参数T2


如果把第一个模板中多余的T2去掉,使用这种源文件

template<class T1>
void foo(T1, T1);

template<class T1, class T2>
void foo(T1, T2);

int main()
{
foo(1,1);
}

编译器总是会选择第一个选项(如果 T1T2 当然是相同的)因为它更专业。

另一种选择是给T2一个默认值。然后第一个变体也可以从 foo(1,1) 实例化。

template<class T1, class T2 = void>
void foo(T1, T1);

另一个有趣的事情是:

#include <iostream>

template<class T1, class T2>
void foo(T1, T1)
{ std::cout << "First choice!\n"; }

template<class T1, class T2>
void foo(T1, T2)
{ std::cout << "Second choice!\n"; }

int main()
{
foo<int,int>(1,1);
}

这将在运行时输出:

First choice!

我不完全确定,但我相信这是因为在推导的情况下(即使这里没有执行),对于第一个变体,编译器只需要推导一种类型而不是两种,这使得它是更专业的选择。

关于c++ - 函数模板 - 编译器在使用相同类型调用时选择具有不同参数类型的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43711907/

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