我可以看到幾個解決方案,涉及鏈表,但他們都是,我很害怕,對接醜陋;)
然而,考慮到一個列表的所有節點都屬於一個共同的實體Network
,也就是說,我想,我們的魔術牌。如果我們放棄列表的想法,而是瞄準網絡中的「定位」節點,那麼它變得更容易!
template <typename Network, unsigned Index, unsigned Size>
class Node {
public:
private:
Network* m_network;
Eigen::Matrix<float, Size, Size> m_matrix;
}; // class Node
而網絡:
template <unsigned Size0, unsigned Size1, unsigned Size2>
class Network {
public:
template <unsigned Index>
auto access() -> decltype(m_nodes.get<Index>()) {
return m_nodes.get<Index>();
}
template <unsigned Index>
auto get() const -> decltype(m_nodes.get<Index>()) {
return m_nodes.get<Index>();
}
private:
std::tuple< Node<Network, 0u, Size0>,
Node<Network, 1u, Size1>,
Node<Network, 2u, Size2>> m_nodes;
};
最後,重複?
template <typename Network, unsigned Index, unsigned Size>
auto Node<Network, Index, Size>::prev() -> decltype(m_network->access<Index-1>()) {
return m_network->access<Index-1>();
}
template <typename Network, unsigned Index, unsigned Size>
auto Node<Network, Index, Size>::next() -> decltype(m_network->access<Index+1>()) {
return m_network->access<Index+1>();
}
好了,除了我們現在看到自己有點雞和蛋的問題......我們可以出,雖然通過嵌套Network
類中的Node
定義騙我們的方式。然而,我可能會這麼做,爲什麼不接受迭代應該始終從網絡類開始?
最後,這裏是我的建議:
template <unsigned Size>
class Node {
public:
// ...
private:
Eigen::Matrix<float, Size, Size> m_matrix;
};
template <unsigned Size>
std::ostream& operator<<(std::ostream& out, Node<Size> const&) {
return out << "Node<" << Size << ">";
}
template <unsigned S, unsigned... Sizes>
class Network {
private:
// Hack for gcc, using m_nodes in decltype requires that it's already been declared
typedef std::tuple< Node<S>, Node<Sizes>... > Nodes;
Nodes m_nodes;
public:
static constexpr unsigned Size() { return sizeof...(Sizes) + 1; }
template <unsigned Index>
auto access() -> decltype(std::get<Index>(this->m_nodes)) {
return std::get<Index>(this->m_nodes);
}
template <unsigned Index>
auto get() const -> decltype(std::get<Index>(this->m_nodes)) {
return std::get<Index>(this->m_nodes);
}
}; // class Network
當然,一個Node
不再知道它的位置,但你可以在一個迭代好吧包起來:
template <typename Network, unsigned Index>
class NetworkIterator {
private:
// Hack for gcc, using m_network in decltype requires that it's already been declared
Network& m_network;
public:
static_assert(Index < Network::Size(), "Index cannot exceed network size by more than one");
NetworkIterator(Network& n): m_network(n) {}
auto element() -> decltype(this->m_network.template access<Index>()) {
return m_network.template access<Index>();
}
template <unsigned U = Index - 1>
NetworkIterator<Network, U> prev() {
return NetworkIterator<Network, U>(m_network);
}
template <unsigned U = Index + 1>
NetworkIterator<Network, U> next() {
return NetworkIterator<Network, U>(m_network);
}
}; // class NetworkIterator
是的,it works。
我在這裏出去走走,並建議你可能不想做你認爲你想做的事。模板是編譯時的結構,並不便於運行時檢查。即使您可以構建一些標記聯合類型的小工具或存儲無效指針,您仍然必須在運行時處理結果,這是不切實際的。 –
這個'Size'參數控制着什麼數據結構的大小?你是說每個節點的大小不同,它不是一個列表中所有節點的常量? –
也許術語»鏈接列表«是誤導性的。我想用固定數量的節點(每個節點常量,每個節點具有另一個大小值)來設置列表。編譯時已知節點的數量和大小。 – wuschelhase