具有特征的力类型定义
Force type definition with traits
我写了这些表示图形的类:
class Node{
public:
typedef std::vector<Node>::iterator iterator;
iterator begin() {return neigh.begin();}
iterator end() {return neigh.end();}
public:
Node(std::string n) : name(n) {}
std::string getName() {return name; }
void addNeigh(Node n){
neigh.push_back(n);
}
private:
std::string name;
std::vector<Node> neigh;
};
class Map{
public:
typedef std::vector<Node>::iterator iterator;
iterator begin() {return nodes.begin();}
iterator end() {return nodes.end();}
public:
Map(std::string n) : map_name(n) {}
void addNode(Node n){
nodes.push_back(n);
}
std::string getName() { return map_name; }
int getNumNodes() {return nodes.size();}
private:
std::string map_name;
std::vector<Node> nodes;
};
然后我想编写一个函数printGraph
,它使用特征打印一些图形信息:
template<typename T>
struct GraphTraits{
};
template<>
struct GraphTraits<Map>{
typedef Map::iterator node_iterator;
static node_iterator node_begin(Map map){ return map.begin();}
static node_iterator node_end(Map map) { return map.end();}
static std::string getName(Map m) {return m.getName();}
};
template<typename T>
void printGraph(T t){
std::cout << std::endl
<< "--------------------------------------" << std::endl
<< "| printGraph |" << std::endl
<< "--------------------------------------" << std::endl;
std::cout << "Graph name: " << GraphTraits<T>::getName(t) << std::endl;
for(GraphTraits<T>::node_iterator it = GraphTraits<T>::node_begin(t), e = GraphTraits<T>::node_end(t);
it != e; ++it) {
std::cout<< (*it).getName() << std::endl; }
}
如果我尝试编译此代码,则会出现以下错误:
grafo.cpp:75:37: error: expected ';' in 'for' statement specifier
for(GraphTraits<T>::node_iterator it = GraphTraits<T>::node_begin(t), e = GraphTraits<T>::node_end(t);
^
grafo.cpp:75:37: error: use of undeclared identifier 'it'
grafo.cpp:75:73: error: use of undeclared identifier 'e'
for(GraphTraits<T>::node_iterator it = GraphTraits<T>::node_begin(t), e = GraphTraits<T>::node_end(t);
^
grafo.cpp:76:9: error: use of undeclared identifier 'it'
it != e; ++it) {
^
grafo.cpp:76:15: error: use of undeclared identifier 'e'
it != e; ++it) {
^
grafo.cpp:76:16: error: expected ')'
it != e; ++it) {
^
grafo.cpp:75:6: note: to match this '('
for(GraphTraits<T>::node_iterator it = GraphTraits<T>::node_begin(t), e = GraphTraits<T>::node_end(t);
^
grafo.cpp:76:20: error: use of undeclared identifier 'it'
it != e; ++it) {
^
grafo.cpp:75:23: error: unexpected type name 'node_iterator': expected expression
for(GraphTraits<T>::node_iterator it = GraphTraits<T>::node_begin(t), e = GraphTraits<T>::node_end(t);
^
grafo.cpp:104:3: note: in instantiation of function template specialization 'printGraph<Map>' requested here
printGraph(mappa);
^
我可以解决并编译成功替换:
for(GraphTraits<T>::node_iterator....
跟:
for(GraphTraits<Map>::node_iterator....
但这printGraph
失去了它的普遍性。
有人可以给我一些提示来解决问题吗?
一般来说,是否可以使用特征来强制数据类型定义?我的意思是:
template<typename T>
struct ATraits{
-> type "iterator" must be defined
};
这样每个专业都必须定义:
typedef ..something.. iterator;
您忘记使用 typename
关键字。
在GraphTraits<Map>::node_iterator
中,编译器知道使用了什么特化GraphTraits
,并且可以确定node_iterator
是一个typedef。
在GraphTraits<T>::node_iterator
,它不知道将使用什么专业化,因为T
还不知道。 因此,它假定node_iterator
是成员变量,而不是类型。 你必须纠正这个假设。 说typename GraphTraits<T>::node_iterator
要要求GraphTraits
的每个专业化都提供 typedef,您需要"概念",这些概念是为 C++11 提出的,但必须推迟到未来的版本。 所以这在今天的C++是不可能的。 但是,每当您实际使用 printGraph
时(正式地,在实例化printGraph<T>
函数模板的每个模板函数实例期间),编译器都会仔细检查GraphTraits<T>::node_iterator
是否真的是一种类型(因为现在它知道T
并且可以执行重载解析)。
相关文章:
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 列表参数的类型定义
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 关于 C++ 中的函数类型定义
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- 将使用/类型定义限制为类范围
- 模板类型定义?
- C++:模板类的类型定义
- 如何对命名空间限定类型进行类型定义?
- 此递归模板类型定义是否有效C++?
- 具有调整对齐方式的类型定义
- C++从抽象类型定义类成员
- 用于C++代码的 API 监视器类型定义 (XML)
- 如何将result_of与函数类型定义一起使用
- 在C++的适当类型定义位置
- 如何根据模板类型定义浮点常量?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 参数化类的别名(或类型定义)内部类
- 如果我想从类型"T"定义元素的容器(来自 STL),那么"T"必须使用默认构造函数?