我一直在寻找这个问题在这里找到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; }
这是没有提供实际上修正编译错误以及代码没有正常运行的答案。为了清楚起见,我正在询问关于此代码段的问题。 OP最初尝试对模板类型进行模式匹配,但对模板模板参数的语法不正确。当我通过我的IDE跑了答案,编译器&调试器{MSVS 2017年CE}在64位英特尔Windows 7计算机上运行我碰巧注意到它们的主要功能是,在OP的函数调用:
f(std::list<double>{}); f(std::vector<std::tuple<int>>{});
第二个函数调用实际上是调用第一个函数模板而不是第二个。这确实引起了几个问题:
- 这是由于编译器优化?
- 这是重载解析的结果吗?
- 在编译器的底层实际发生了什么,它在 选择使用第二个函数模板?
- 或者这是MSVC编译器的错误吗?
呃,你会得到输出“1 2”吗?或者您是否从调试器中看到的结论得出了“第二个函数调用实际上调用第一个函数模板”的结论? –
@DanielJour我打印的值是'1'而不是'2',因此它调用第一个函数而不是第二个函数。 –
这是MSVC编译器中的一个错误。 –