【发布时间】:2017-06-13 02:23:00
【问题描述】:
我正在查看这里发现的这个问题Template function overload for type containing a type
OP user2079802 为他/她的问题提供了此代码:
我正在尝试执行以下操作:
#include <iostream> #include <vector> #include <tuple> template <typename T> void f(T t) { std::cout << "1" << std::endl; } template <typename T, typename V> void f(T<std::tuple<V>> t) { std::cout << "2" << std::endl; } int main() { f(std::list<double>{}); // should use first template f(std::vector<std::tuple<int>>{}); // should use second template }在 C++14 中最简单的方法是什么?我以为我可以通过这种方式进行模式匹配,但编译器不会有它。
而songyuanyao 提供了这个答案:
模板参数
T用作模板名称,因此应声明为template template parameter。例如template <template <typename...> class T, typename V> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void f(T<std::tuple<V>> t) { std::cout << "2" << std::endl; }
提供的答案确实修复了编译错误并且代码确实运行正常。为了清楚起见,我正在询问有关此代码 sn-p 的问题。 OP 最初试图对模板类型进行模式匹配,但模板模板参数的语法不正确。当我通过在 64 位 Intel Windows 7 机器上运行的 IDE、编译器和调试器 {MSVS 2017 CE} 运行答案时,我碰巧注意到在 OP 的函数调用中的主函数:
f(std::list<double>{}); f(std::vector<std::tuple<int>>{});
第二个函数调用实际上是调用第一个函数模板而不是第二个。这确实提出了几个问题:
- 这是由于编译器优化造成的吗?
- 这是重载解决的结果吗?
- 当编译器运行时,编译器内部实际发生了什么 是否选择使用第一个函数模板而不是第二个?
- 或者这是 MSVC 编译器的错误?
【问题讨论】:
-
呃,你得到输出“1 2”了吗?还是您从调试器中看到的“第二个函数调用实际上是在调用第一个函数模板”得出这样的结论?
-
@DanielJour 我得到了
1而不是2的打印值,所以它调用的是第一个函数而不是第二个。 -
这是MSVC编译器的一个bug。
-
@n.m.检查我的答案,看看它实际上不是 MSVC 中的错误(还)
标签: c++ templates compiler-optimization overload-resolution