C 类使用模板
C++ class using a template
i正在实现C 中图的简单限制数据结构。我实现的第一个"类"是"节点"或装饰节点。经过很少的研究,我从课程到模板,就像这样。
template <typename T>
class Node {
public:
Node ( T element ) {this->_element=element;}
//Setters
void heuristic ( double heuristic ) {this->_heuristic=heuristic;}
void visited ( bool visited ) {this->_visited=visited;}
void element ( T element ) {this->_element=element;}
void incrementOrder () {this->_order++;}
void decrementOrder () {this->_order--;}
//Getters
int order () {return this->_order;}
double heuristic () {return this->_heuristic;}
T element () {return this->_element;}
bool isVisited () {return this->_visited;}
protected:
double _heuristic;
bool _visited;
T _element;
int _order;
};
是时候该实施"边缘"类了。我是类似的东西:
#include "Node.hpp"
template <typename T>
class Edge {
public:
Edge (Node<T>& leftNode, Node<T>& rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;}
Node<T> leftNode () {return this->_leftNode;}
Node<T> rightNode () {return this->_rightNode;}
void leftNode (Node<T> leftNode) {this->_leftNode=leftNode;}
void rightNode (Node<T> rightNode) {this->_rightNode=rightNode;}
protected:
Node<T> _leftNode;
Node<T> _rightNode;
};
就是这样,构造函数给我带来了问题,在研究之后,我相信是因为"节点"不是一个真实的班级,也不是将"边缘"变成模板。
问题是,无论如何,边缘可以使用此节点而不会变成模板?
谢谢您的时间。
//编辑#1
我希望实现尽可能一般,这就是为什么我认为边缘类应该具有属性类型节点。
主要块如下:
int main(){
Node<int> *n1 = new Node<int>(1);
Node<int> *n2 = new Node<int>(2);
Edge<int> *e = new Edge<int>(n1, n2);
return 0;
}
错误消息是:
g++ -Wall --std=c++11 -Iinclude/ src/Main.cpp -o exe/main
src/Main.cpp: In function ‘int main()’:
src/Main.cpp:11:16: warning: unused variable ‘e’ [-Wunused-variable]
Edge<int> *e = new Edge<int>(n1, n2);
^
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp: In instantiation of ‘Edge<T>::Edge(Node<T>*, Node<T>*) [with T = int]’:
src/Main.cpp:11:40: required from here
include/Edge.hpp:8:53: error: no matching function for call to ‘Node<int>::Node()’
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: candidate: Node<T>::Node(T) [with T = int]
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:17:5: note: candidate expects 1 argument, 0 provided
include/Node.hpp:14:7: note: candidate: constexpr Node<int>::Node(const Node<int>&)
class Node {
^
include/Node.hpp:14:7: note: candidate expects 1 argument, 0 provided
include/Node.hpp:14:7: note: candidate: constexpr Node<int>::Node(Node<int>&&)
include/Node.hpp:14:7: note: candidate expects 1 argument, 0 provided
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:53: error: no matching function for call to ‘Node<int>::Node()’
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: candidate: Node<T>::Node(T) [with T = int]
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:17:5: note: candidate expects 1 argument, 0 provided
include/Node.hpp:14:7: note: candidate: constexpr Node<int>::Node(const Node<int>&)
class Node {
^
include/Node.hpp:14:7: note: candidate expects 1 argument, 0 provided
include/Node.hpp:14:7: note: candidate: constexpr Node<int>::Node(Node<int>&&)
include/Node.hpp:14:7: note: candidate expects 1 argument, 0 provided
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:69: error: ambiguous overload for ‘operator=’ (operand types are ‘Node<int>’ and ‘Node<int>*’)
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:14:7: note: candidate: Node<int>& Node<int>::operator=(const Node<int>&) <near match>
class Node {
^
include/Node.hpp:14:7: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:69: error: invalid user-defined conversion from ‘Node<int>*’ to ‘const Node<int>&’ [-fpermissive]
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: candidate is: Node<T>::Node(T) [with T = int] <near match>
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:17:5: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:69: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
include/Edge.hpp:8:69: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: initializing argument 1 of ‘Node<T>::Node(T) [with T = int]’
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:14:7: note: candidate: Node<int>& Node<int>::operator=(Node<int>&&) <near match>
class Node {
^
include/Node.hpp:14:7: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:69: error: invalid user-defined conversion from ‘Node<int>*’ to ‘Node<int>&&’ [-fpermissive]
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: candidate is: Node<T>::Node(T) [with T = int] <near match>
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:17:5: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:69: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
include/Edge.hpp:8:69: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: initializing argument 1 of ‘Node<T>::Node(T) [with T = int]’
Node ( T element ) {this->_element=element;}
^
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:69: error: conversion to non-const reference type ‘class Node<int>&&’ from rvalue of type ‘Node<int>’ [-fpermissive]
Edge (Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=ri
^
include/Edge.hpp:8:95: error: ambiguous overload for ‘operator=’ (operand types are ‘Node<int>’ and ‘Node<int>*’)
(Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:14:7: note: candidate: Node<int>& Node<int>::operator=(const Node<int>&) <near match>
class Node {
^
include/Node.hpp:14:7: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:95: error: invalid user-defined conversion from ‘Node<int>*’ to ‘const Node<int>&’ [-fpermissive]
(Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: candidate is: Node<T>::Node(T) [with T = int] <near match>
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:17:5: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:95: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
(Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;
^
include/Edge.hpp:8:95: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: initializing argument 1 of ‘Node<T>::Node(T) [with T = int]’
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:14:7: note: candidate: Node<int>& Node<int>::operator=(Node<int>&&) <near match>
class Node {
^
include/Node.hpp:14:7: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:95: error: invalid user-defined conversion from ‘Node<int>*’ to ‘Node<int>&&’ [-fpermissive]
(Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;
^
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: candidate is: Node<T>::Node(T) [with T = int] <near match>
Node ( T element ) {this->_element=element;}
^
include/Node.hpp:17:5: note: conversion of argument 1 would be ill-formed:
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:95: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
(Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;
^
include/Edge.hpp:8:95: error: invalid conversion from ‘Node<int>*’ to ‘int’ [-fpermissive]
In file included from include/Edge.hpp:2:0,
from include/Graph.hpp:1,
from src/Main.cpp:2:
include/Node.hpp:17:5: note: initializing argument 1 of ‘Node<T>::Node(T) [with T = int]’
Node ( T element ) {this->_element=element;}
^
In file included from include/Graph.hpp:1:0,
from src/Main.cpp:2:
include/Edge.hpp:8:95: error: conversion to non-const reference type ‘class Node<int>&&’ from rvalue of type ‘Node<int>’ [-fpermissive]
(Node<T> *leftNode, Node<T> *rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;
^
Makefile:19: recipe for target 'default' failed
make: *** [default] Error 1
您的成员_leftNode
和_rightNode
需要初始化,但Node
没有 default 构造函数。您当前的构造函数不会初始化它们,而是试图在构造函数主体中分配新值。
您可以修改Edge
构造函数以在其成员initializer列表中初始化它们:
Edge(Node<T>& leftNode, Node<T>& rightNode):
_leftNode(leftNode), _rightNode(rightNode)
{
}
或者您可以将默认构造函数添加到Node
-一个不进行参数。
template <typename T>
class Node {
public:
Node() = default;
// ...
此外,您可以使用Node( T element )
构造函数进行相同的操作,并在可能的情况下使用const
参考,例如Node( const T& element )
和Edge(const Node<T>& leftNode, const Node<T>& rightNode)
。
https://godbolt.org/g/r7ms4a
如果您的用例不需要有关element
的信息(例如,编写只需访问图形而无需访问其节点数据的编写通用算法(,则可以尝试尝试将数据分开界面。这是一个总体想法:
#include <iostream>
// Note: don't do this
using namespace std;
将节点元数据拆分为非策略类INode
:
class INode {
public:
void heuristic(double heuristic) { this->_heuristic = heuristic; }
void visited(bool visited) { this->_visited = visited; }
void incrementOrder() { this->_order++; }
void decrementOrder() { this->_order--; }
//Getters
int order() { return this->_order; }
double heuristic() { return this->_heuristic; }
bool isVisited() { return this->_visited; }
protected:
double _heuristic;
bool _visited;
int _order;
};
创建一个模板包装器以保存数据
template <typename T>
class Node : public INode {
public:
Node(T element) { this->_element = element; }
void element(T element) { this->_element = element; }
T element() { return this->_element; }
protected:
T _element;
};
如果Edge
不需要了解element
,则可以使用INode
S。
class Edge {
public:
//Edge (Node<T>& leftNode, Node<T>& rightNode) {this->_leftNode=leftNode;this->_rightNode=rightNode;}
Edge(INode leftNode, INode rightNode)
: _leftNode(leftNode)
, _rightNode(rightNode)
{
}
INode leftNode() { return this->_leftNode; }
INode rightNode() { return this->_rightNode; }
void leftNode(INode leftNode) { this->_leftNode = leftNode; }
void rightNode(INode rightNode) { this->_rightNode = rightNode; }
protected:
INode _leftNode;
INode _rightNode;
};
您现在可以使用以下内容:
int main()
{
Node<int> l(1);
Node<int> r(2);
Edge edge(l, r);
}
请将其视为伪代码以演示这个想法 - 即使它编译了对象切片的问题。您将要确保您有虚拟类和使用(const(引用。
直到用特定类型实例化模板类。此外,模板Node<int>
与Node<char>
不同。如果您希望Edge类能够处理Node
,而无需Edge类是模板类本身,则需要在边缘类中明确指定节点类型,例如:
Edge(const Node<int>& leftNode, const Node<int>& rightNode) { ... }
,或者您必须将边缘类变成模板,以便您能够使用不同类型的节点来处理边缘。
- 没有找到相关文章