模板函数中的静态变量失败
Static variable in template function fail
头文件 (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)
编辑:
在"101010"简洁的解释之后,来自 cplusplus.com:
由于映射中的元素键是唯一的,因此插入操作 检查每个插入元素是否具有与该元素等效的键 容器中已有的元素,如果是,则该元素不是 插入,返回此现有元素的迭代器(如果 函数返回一个值)。
正如注释中正确@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
相关文章:
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 模板基类中的静态变量
- 类和静态变量
- 不同作用域中的静态变量和全局变量
- 静态变量声明和定义
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在类中继承静态变量?
- "local scope"中的 C++ 初始化静态变量
- 使用静态变量的递归调用的不同输出
- 复制文件流C++静态变量
- 跨模板化函数编译的静态变量
- C++编译器是否优化了顺序静态变量读取?
- C++,每个循环初始化一个新的静态变量
- (为什么)我们可以在初始化中将非静态类成员分配给静态变量吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- 程序如何知道静态变量是否需要初始化?
- 类外的静态变量实例化
- 无法解析静态变量
- 函数局部静态变量:从性能角度来看的优点/缺点
- 访问从 CPP 文件到其他头文件的静态变量