I was looking at this question found here Template function overload for type containing a type
Where the OP user2079802 provided this code for his/her question:
I'm trying to do the following:
#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 }
What is the simplest way to do this in C++14? I thought that I could sort of pattern match in this way but the compiler won't have it.
And songyuanyao provided this answer:
The template parameter
T
is used as a template-name, so it should be declared as template template parameter. e.g.template <template <typename...> class T, typename V> // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void f(T<std::tuple<V>> t) { std::cout << "2" << std::endl; }
LIVE
The answer that was provided did in fact fix the compilation errors and the code does run correctly. I'm asking a question about this code snippet for clarity. The OP was originally trying to pattern match the template types but had improper syntax for template template parameters. When I ran the answer through my IDE, Compiler & Debugger {MSVS 2017 CE} running on a 64bit Intel Windows 7 machine I happen to notice that in the OP's function calls in their main function:
f(std::list<double>{}); f(std::vector<std::tuple<int>>{});
That the 2nd function call is in fact calling the 1st function template and not the 2nd. This does raise a couple of questions:
- Is this happening due to compiler optimizations?
- Is this a result of overload resolution?
- What is actually happening under the hood of the compiler when it is choosing to use the first function template over the 2nd?
- Or is this a bug with MSVC compiler?