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

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

Cross-Compiling Linux Kernel for Raspberry Pi - ${CCPREFIX}gcc -v does not work -

java.lang.NoClassDefFoundError When Creating New Android Project -