模板结构的矢量
vector of template struct
using namespace std;
#include <vector>
#include <string>
template <class T>
struct ValNode {
string id;
T value;
};
class ValTable {
public:
ValTable();
template <class T>
void add(string,T);
const bool find(string);
void remove(string);
private:
template<class T>
std::vector<ValNode<T>*> vals;
};
编译器错误:error: data member 'vals' cannot be a member template
我确实尝试在结构中使用 T* 值,但我没有成功。我还没有使用代码中的任何函数。只是试图将其编译成 *.o 文件(也带有.cpp文件)。
正如错误所说,变量(包括数据成员)不能是模板;只有类和函数可以是。
看起来您希望表能够保存各种不同类型的值,这些值在运行时根据传递给add()
的类型指定。为此,您需要动态类型,C++ 中不直接支持这些类型。你可以考虑像Boost.Any或Boost.Variant 这样的库。
另一方面,也许您只想在每个表中存储单个类型,并在不同的表中存储不同的类型。在这种情况下,类本身需要是一个模板:
template <typename T>
class ValTable {
public:
ValTable();
void add(string,T);
const bool find(string);
void remove(string);
private:
std::vector<ValNode<T>*> vals;
};
在C++中,可以在类中使用模板方法,但不能在模板数据成员中使用模板方法。例如:
template<typename T, int n>
struct FixedVector {
T x[n];
FixedVector() {
for (int i=0; i<n; i++) x[i] = 0;
}
template<typename C>
void copy(const C& container) {
if (container.size() != n) {
throw std::runtime_error("Wrong size");
}
int j = 0;
for (typename C::const_iterator i=container.begin(),
e=container.end();
i!=e;
++i)
{
x[j++] = *i;
}
}
};
使用上面的类,您可以声明FixedVector<int, 5> f
并调用f.copy(v)
其中v
可以是例如向量或列表或任何具有size
begin
和end
的东西。因此FixedVector::copy
是一个模板方法,这意味着编译器将为要传递给函数的每个不同类型生成不同的版本。
std::vector<double> y;
y.push_back(3.4); y.push_back(5.6); y.push_back(7.8);
std::list<unsigned char> z;
z.push_back('a'); z.push_back('b'); z.push_back('c');
FixedVector<int, 3> v;
v.copy(y); // This is ok
v.copy(z); // This is ok too
C++不允许模板数据成员,因为这意味着根据您在特定编译单元中使用的类型数量而具有不同的类大小,并且这与一次一个单元的C++编译模型不符。
添加方法很好,因为它不会影响类大小,并且可以通过避免从不同的编译单元中提取同一方法的多个副本来在链接时修复所有内容。
将ValTable
声明为模板
template <class T>
class ValTable{
public:
ValTable();
//template <class T>
void add(string,T);
const bool find(string);
void remove(string);
private:
//template<class T>
std::vector<ValNode<T>*> vals;
};
您将无法做到这一点ValTable
需要成为模板
你可以有这个:
template <class T> //Make the class as template
class ValTable {
public:
ValTable();
template <class X>
void add(string,X);
const bool find(string);
void remove(string);
private:
//template<class T>
std::vector<ValNode<T>*> vals;
};
不能有模板成员值:每个翻译单元可以访问不同的实例化,从而导致不同的 ibject 布局。您需要以某种方式分解类型。
标准库按照您想要的std::locale
做一些事情:每个std::locale
存储不同类型对象的集合。它是社会目的,不能直接用于您的目的。
基本思想是自动将用于int
的每个类型映射到然后用于将类型映射到实例。然后,vals
成员将是查找正确实例的函数模板。粗略的轮廓可能如下所示:
int type_index_alloc() {
static std::atomic<int> current(0);
return ++current;
}
template <typename T>
int type_map() {
static int rc = type_index_alloc();
}
class container {
struct base { virtual ~base() {} };
template <typename T>
struct value: base { T v; };
std::map<int, std::shared_ptr<base>> vals_;
public:
T& vals() {
std::shared_ptr<base>& rc(vals_[type_map<T>()]);
if (!rc) {
rc = std::make_shared<value<T>>()); }
return static_cast<value<T>&>(*rc).v;
}
};
这只是试图展示事情是如何设置的:我目前无法访问编译器。此外,代码示例仅提供对类型为 T
对象的访问,但可以轻松地将其更改为使用 std::vector<T>
。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- vscode g++链路故障:体系结构x86_64的未定义符号
- C++概念:如何使用'concept'检查模板化结构的属性?