簡體   English   中英

C ++:指向數據成員或特征的指針?

[英]C++: pointers to data members or traits?

我正在使用C ++中的一些二叉樹算法進行練習,並嘗試編寫盡可能通用的代碼。 特別是,我希望我的函數(算法)能夠對任何(當然在某種程度上)樹狀數據結構進行操作。

樹節點結構可能以不同的方式定義,例如:

struct binary_tree_node
{
    int data;
    struct binary_tree_node *left;
    struct binary_tree_node *right;
};

或像這樣:

struct binary_tree_node2
{
    long key;
    struct binary_tree_node2 *first_child;
    struct binary_tree_node2 *second_child;
};

或其他方式,但與該模式非常相似。 因此,我希望我的函數/算法能夠使用這些或類似數據結構中的任何一個。

例如,這是我定義一個簡單函數的方式:

template <typename TreeNode, typename DataType = typename TreeNode::data_type>
TreeNode*
binary_tree_new_node(DataType value = DataType(),
                     DataType  TreeNode::* data  = &TreeNode::data,
                     TreeNode* TreeNode::* left  = &TreeNode::left,
                     TreeNode* TreeNode::* right = &TreeNode::right)
{
    TreeNode *newnode = new TreeNode();
    newnode->*data  = value;
    newnode->*left  = nullptr;
    newnode->*right = nullptr;
    return newnode;
}

因此,可以將函數與您選擇的任何合適的樹節點類型一起使用。 如果數據成員具有不同的名稱(不是dataleftright ),則可以調用該函數並將指針傳遞給相應的數據成員。 這樣,函數就不依賴於(或至少可以自行調整)輸入類型的數據成員的命名方式。

到目前為止,它運行良好,但是隨着我實現越來越多的功能,我已經厭倦了這些指向數據成員的指針參數,這些參數必須作為函數的可選參數列出。 那么有沒有更好的方法來解決這個問題? 也許是某種特質? 還是其他方式?

我想盡可能減少對輸入類型的要求。 例如,不應僅強制客戶端程序定義樹節點類型以外的任何內容。 也不應強迫它使用/派生自任何提供的類型或模板。 當然,客戶端程序可能會重復使用某些提供的模板,例如以下我也定義的模板,但實際上不應強行使用。

template<typename T>
struct binary_tree_node
{
    using data_type = T;
    data_type data;
    struct binary_tree_node *left;
    struct binary_tree_node *right;
};

這里有哪些可用選項? 有什么意義嗎? :)

提前致謝

STL集合庫的工作方式是,樹庫的作者將提供節點類,以便模板的所有用戶需要做的就是提供數據。 您似乎想要的另一個選擇是侵入性數據結構(這對Google來說是個好主意)。 對於這些,您有兩種選擇,第一個是要求數據成員為left,right和data。 其次,需要使用具有特定名稱的訪問功能,以便模板可以找到它們。 第三個要求將函子作為模板參數傳遞,因此您可以使用函子來查找所需的數據。 我個人認為STL方式最不混亂,其次是仿函數方法。

為了使您的算法盡可能通用,我建議使用仿函數。 您的binary_tree_new_node看起來像

template<typename G, typename L, typename R, typename AT, typename AD, typename D>
auto binary_tree_new_node(
    G generator,
    L left,
    R right,
    AT assign_tree,
    AD assign_data,
    D data) ->decltype( generator() )
{
    auto  tree = generator();
    auto& l    = left(tree);
    auto& r    = right(tree);
    assign_data(tree, data);
    assign_tree(l, nullptr);
    assign_tree(r, nullptr);
    return tree;
}

對於您的binary_tree_node,函子將如下所示:

// WARNING!!! Very dangerous code!!!

binary_tree_node* generator()
{
    return new binary_tree_node;
}

binary_tree_node*& left(binary_tree_node* tree)
{
    return tree->left;
}

binary_tree_node*& right(binary_tree_node* tree)
{
    return tree->right;
}

void assign_data(binary_tree_node* node, int data)
{
    node->data = data;
}

void assign_tree(binary_tree_node*& node, binary_tree_node* data)
{
    node = data;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM