有没有办法在编译时通过其名称/指针获取函数类型并将其用作模板参数的默认值?
考虑以下代码:
template <typename TreeNode>
void default_visitor(TreeNode* node)
{
std::cout << node->data << std::endl;
}
template <typename TreeNode, typename Visitor>
void binary_tree_traverse(TreeNode* root, Visitor visitor)
{
/* some tree traversal calling the visitor for a node: */
visitor(root);
}
之后,binary_tree_traverse()
可以使用任何访问者类型调用,例如:
// call with lambda
binary_tree_traverse(root,
[](BinaryTreeNode *node)
{ std::cout << node->data << std::endl; });
// call with default_visitor() or anything else...
binary_tree_traverse(root, default_visitor<BinaryTreeNode>);
但是,我也希望能够省略访问者参数并像这样简单地调用函数:
binary_tree_traverse(root);
在这种情况下,它应该表现得好像它是用 调用的default_visitor<>
。
问题是如何相应地更改模板函数定义?像下面这样的东西将是一个理想的解决方案:
template <typename TreeNode,
typename Visitor = ?typeof? default_visitor<TreeNode>>
void binary_tree_traverse(TreeNode* root,
Visitor visitor = default_visitor<TreeNode>)
{
visitor(root);
}
知道怎么做吗?甚至可能吗?
另一种解决方案可能是使用模板专业化(或者它的正确名称是什么?)并定义函数的额外版本(在这种情况下可以删除第二个函数参数,但想法是相同的):
template<typename TreeNode>
using typeof_default_visitor = void(*)(TreeNode*);
template <typename TreeNode>
void binary_tree_traverse(TreeNode* root,
typeof_default_visitor<TreeNode> visitor = default_visitor<TreeNode>)
{
// call the generic version:
binary_tree_traverse<TreeNode, typeof_default_visitor<TreeNode>>(root, visitor);
}
但这看起来不太好,不是吗?为了默认参数而额外的 [dummy] 函数似乎有点过头了。解决这个问题的正确(真正的 C++)方法是什么?这里有哪些选择?