头文件(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
程序文件:
#include <iostream>
#include "test.h"
void ShowM(int x, const MIS &m)
{
std::cout << "\n---" << x << "---\n";
for (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;
}
输出:
---1---
1 -> 1
2 -> four
---2---
1 -> 1
2 -> two
3 -> 3.1415
4 -> four
5 -> 5
---3---
1 -> 1
2 -> two
3 -> 3.1415
4 -> four
5 -> 5
为什么第一个模板函数无法正确构建地图?结果很奇怪。 (在Linux上使用gcc)
编辑:
关注&#39; 101010&#39;整洁的解释,来自cplusplus.com:
因为地图中的元素键是唯一的,所以插入操作 检查每个插入的元素是否具有与该元素等效的键 已经在容器中的元素,如果是,则元素不是 插入,将迭代器返回到此现有元素(如果是 函数返回一个值。)
答案 0 :(得分:2)
正如评论中提到的@immibis正确一样,由于模板参数推断,生成了模板函数mkpair1
的3个模板实例,即:
mkpair1<int>(...) // for inputs 1, 5
mkpair1<double>(...) // for input 3.1415
mkpair1<const char*>(...) // for input "tow" and "four"
因此,可变参数模板扩展看起来像:
m = { mkpair1<int>(1),
mkpair1<const char*>("two"),
mkpair1<double>(3.1415),
mkpair1<const char*>("four"),
mkpair1<int>(5)
};
现在,由于生成的每个模板实例化都定义了不同的static int i
,因此您将拥有以下插入方案:
m.insert(std::make_pair(1, "1"); // OK
m.insert(std::make_pair(1, "two"); // ignored due to key 1 already exists
m.insert(std::make_pair(1, "3.1415"); // ignored due to key 1 already exists
m.insert(std::make_pair(2, "four"); // OK
m.insert(std::make_pair(2, "5")); // ignored due to key 2 already exists
因此,你得到了结果:
---1---
1 -> 1
2 -> four