c++ - Static variable in template function fail -
header file (test.h):
#ifndef _test_h_ #define _test_h_ #include <string> #include <sstream> #include <map> typedef std::map<int, std::string> mis; //-----1----- template<typename t> const std::pair<int, std::string> mkpair1(t t) { static int i=0; std::stringstream ss; ss << t; return std::pair<int, std::string>(++i, ss.str()); } template<typename...any> void mkmap1(mis &m, any...any) { m = { mkpair1(any)... }; }; //-----2----- template<typename t> const std::pair<int, std::string> mkpair2(int i, t t) { std::stringstream ss; ss << t; return std::pair<int, std::string>(i, ss.str()); } template<typename...any> void mkmap2(mis &m, any...any) { static int i=0; m = { mkpair2(++i, any)... }; }; //-----3----- template<typename t> const std::pair<int, std::string> mkpair3(int &i, t t) { std::stringstream ss; ss << t; return std::pair<int, std::string>(++i, ss.str()); } template<typename...any> void mkmap3(mis &m, any...any) { int i=0; m = { mkpair3(i, any)... }; }; #endif
program file:
#include <iostream> #include "test.h" void showm(int x, const mis &m) { std::cout << "\n---" << x << "---\n"; (auto p:m) std::cout << p.first << " -> " << p.second << "\n"; } int main(int argc, const char *argv[]) { mis m; m.clear(); mkmap1(m, 1, "two", 3.1415, "four", 5); showm(1, m); m.clear(); mkmap2(m, 1, "two", 3.1415, "four", 5); showm(2, m); m.clear(); mkmap3(m, 1, "two", 3.1415, "four", 5); showm(3, m); return 0; }
output:
---1--- 1 -> 1 2 -> 4 ---2--- 1 -> 1 2 -> 2 3 -> 3.1415 4 -> 4 5 -> 5 ---3--- 1 -> 1 2 -> 2 3 -> 3.1415 4 -> 4 5 -> 5
why first template functions fail build map correctly? result strange. (using gcc on linux)
edit:
following on '101010' neat explanation, cplusplus.com:
because element keys in map unique, insertion operation checks whether each inserted element has key equivalent 1 of element in container, , if so, element not inserted, returning iterator existing element (if function returns value).
as correctly @immibis mentioned in comments, due template argument deduction there 3 template instantiations of template function mkpair1
generated, namely:
mkpair1<int>(...) // inputs 1, 5 mkpair1<double>(...) // input 3.1415 mkpair1<const char*>(...) // input "tow" , "four"
consequently, variadic template expansion like:
m = { mkpair1<int>(1), mkpair1<const char*>("two"), mkpair1<double>(3.1415), mkpair1<const char*>("four"), mkpair1<int>(5) };
now due fact each template instantiation generated have different static int i
defined well, have following insertion scheme:
m.insert(std::make_pair(1, "1"); // ok m.insert(std::make_pair(1, "two"); // ignored due key 1 exists m.insert(std::make_pair(1, "3.1415"); // ignored due key 1 exists m.insert(std::make_pair(2, "four"); // ok m.insert(std::make_pair(2, "5")); // ignored due key 2 exists
thus rightfully, result:
---1--- 1 -> 1 2 -> 4
Comments
Post a Comment