这可以通过静态键入来完成吗
Can this be done with static typing?
此方法尝试基于密钥(std::string
)选择(std::vector<?>
),其中?
是int
或float
:
template<typename L>
inline void EnsembleClustering::Graph::forNodesWithAttribute(std::string attrKey, L handle) {
// get nodemap for attrKey
auto nodeMap; // ?
auto findIdPair = this->attrKey2IdPair.find(attrKey);
if (findIdPair != this->attrKey2IdPair.end()) {
std::pair<index, index> idPair = findIdPair->second;
index typeId = idPair.first;
index mapId = idPair.second;
// nodemaps are in a vector, one for each node attribute type int, float, NodeAttribute
switch (typeId) {
case 0:
nodeMap = this->nodeMapsInt[mapId];
break;
case 1:
nodeMap = this->nodeMapsFloat[mapId];
break;
}
// iterate over nodes and call handler with attribute
this->forNodes([&](node u) {
auto attr = nodeMap[u];
handle(u, attr);
});
} else {
throw std::runtime_error("node attribute not found");
}
}
该类的相关成员是:
std::map<std::string, std::pair<index, index>> attrKey2IdPair; // attribute key -> (attribute type index, attribute map index)
// storage
std::vector<std::vector<int> > nodeMapsInt; // has type id 0
std::vector<std::vector<float> > nodeMapsFloat; // has type id 1
这将不会编译,因为auto nodeMap
(=std::vector<?>
)未初始化。但是为了初始化它,我必须在编译时知道它的类型。
也许我正在尝试的是静态打字无法完成的。有没有一种C++方法可以实现这一点?
这些都是模板这一事实与此无关。std::vector<std::vector<int> >
和std::vector<std::vector<float> >
是两个完全不相关的类,并表现为这样。如果你真的需要这样,您就必须定义一个抽象基类和两个派生类,每个派生类包装相应的CCD_ 10。但我看不出你将如何使用它,或者甚至定义一个适当的抽象基类,因为类型包含在矢量中的矢量渗透到界面中。您的类型几乎每次通话中的使用也必须有所不同。
如果变量数量有限(即只有float的向量和int的向量),则可以使用boost::variant
来存储它。
定义变体类型,并定义访问者结构:
#include "boost/variant.hpp"
//Define type
typedef boost::variant<std::vector<int>, std::vector<float>> VectorType;
struct VectorTypeVisitor : public boost::static_visitor<void>
{
node& m_u;
VectorTypeVisitor(node& u) : m_u(u) { } //Pass node to visitor in constructor
void operator()(const std::vector<int>& nodeMap) const
{
auto attr = nodeMap[m_u];
handle(m_u, attr);
}
void operator()(const std::vector<float>& nodeMap) const
{
auto attr = nodeMap[m_u];
handle(m_u, attr); //What to do if visitor applied to float
}
}
你的代码可能看起来是这样的:
template<typename L>
inline void EnsembleClustering::Graph::forNodesWithAttribute(std::string attrKey, L handle) {
// get nodemap for attrKey
VectorType nodeMap;
auto findIdPair = this->attrKey2IdPair.find(attrKey);
if (findIdPair != this->attrKey2IdPair.end()) {
std::pair<index, index> idPair = findIdPair->second;
index typeId = idPair.first;
index mapId = idPair.second;
// nodemaps are in a vector, one for each node attribute type int, float, NodeAttribute
switch (typeId) {
case 0:
nodeMap = this->nodeMapsInt[mapId];
break;
case 1:
nodeMap = this->nodeMapsFloat[mapId];
break;
}
// iterate over nodes and call handler with attribute
this->forNodes([&](node u) {
boost::apply_visitor(VectorTypeVisitor(u), nodeMap);
});
} else {
throw std::runtime_error("node attribute not found");
}
}
然而,传递typeId这样的变量来识别变量类型仍然不好。
相关文章:
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 为什么我可以通过引用修改常量返回
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 哪些库可以通过Opencv调整曝光率
- 可以通过复制来初始化集合吗?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 我可以读取静态对象中的文件.txt吗?C++
- 我可以通过取每个数字的模并取和来计算大数的模数吗?
- 我们可以通过 IPC 传递具有动态管理成员的类对象吗?
- 是否可以通过每次在内存中仅保存一个平铺来处理完整的平铺 tiff 图像?
- 两个进程可以通过跟踪附加到同一个 PID 吗?
- 我可以通过将类强制转换为 char* 来序列化类吗?
- Windows 是否可以调用静态库中的 WinMain 函数C++
- 在 C/C++ 中,是否可以通过使用指针更改"important"内存地址的值来创建简单的恶意软件?
- 没有返回类型的静态函数可以通过Windows上的编译,但不能传递Linux上的编译
- 为什么静态本地对象可以通过指针或外部引用访问?
- 可以通过堆分配的地址地址静态变量匹配的值地址值
- 可以通过成员初始化列表初始化静态成员变量
- 是否可以通过编程方式创建函数静态对象
- 这可以通过静态键入来完成吗