首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在这种情况下,模板参数推导是如何工作的?

在这种情况下,模板参数推导是如何工作的?
EN

Stack Overflow用户
提问于 2013-05-07 08:59:34
回答 1查看 527关注 0票数 16

给定这段代码,模板参数推导如何决定对最后一个函数调用执行什么操作?

代码语言:javascript
运行
复制
#include <iostream>

template<typename Ret, typename... Args>
Ret foo(Args&&...) {
    std::cout << "not void\n";
    return {};
}

template<typename... Args>
void foo(Args&&...) {
    std::cout << "void\n";
}

int main() {
    foo(3, 'a', 5.4);            //(1): prints "void"
    foo<int, char>(3, 'a', 5.4); //(2): prints "void"
    foo<int>('a', 5.4);          //(3): prints "not void"
    foo<int>(3, 'a', 5.4);       //(4): prints "not void"
}

(1)看起来很简单。它不能推导出返回类型,所以使用void版本。

(2)显式声明一些参数的类型。第一个模板参数与第一个参数匹配,第二个模板参数与第二个参数匹配,第三个模板参数被推导出来。如果将int用于返回类型,则char将与第一个参数不匹配。

(3)做与(2)相同的事情,但第一个类型不匹配。因此,必须将其推导为返回类型和用于推导两个Args参数的两个参数。

(4)似乎模棱两可。它显式地指定一个模板参数,就像(2)和(3)一样。模板参数与参数匹配,就像(2)一样。但是,它不会将其用作第一个参数并推导出其他两个参数,而是使用显式模板参数作为返回类型,并推导出所有三个Args参数。

为什么(4)看起来跟了(2)一半,然后又用了另一个版本?我最好的猜测是,正在填充的单个模板参数比参数包更匹配。标准在哪里定义了这种行为?

这是用GCC 4.8.0编译的。为了方便起见,这里有一个Coliru上的test run

然而,在Clang 3.1上,(4)由于不明确而无法编译(请参阅注释)。这打开了这两个编译器中有一个有bug的可能性。使这种可能性更大的是这样一个事实,即Visual Studio 2012年11月的CTP编译器给出了与Clang相同的结果,但(4)是不明确的。

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16409588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档