c++ - 如何在编译时通过名称/指针获取模板参数默认值的函数类型?

标签 c++ templates c++11

有没有办法在编译时通过名称/指针获取函数类型并将其用作模板参数的默认值?

考虑以下代码:

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++)方法是什么?这里有哪些选项?

最佳答案

重载,但没有第二个参数而不是默认参数。不,这不是 ~矫枉过正~,这是最简单的解决方案。

template <typename Node, typename Fn>
void foo(Node* root, Fn&& func) {
    // ...
}

template <typename Node>
void foo(Node* root) {
    foo(root, some_default_func);
}

关于c++ - 如何在编译时通过名称/指针获取模板参数默认值的函数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17173737/

相关文章:

c++priority_queuepush/emplace,无需创建临时对象

c++ - 错误 : class template has already been defined

c++ - mingw中#elif的使用

c++ - 与字符串一起使用时对函数模板的 undefined reference (GCC)

c++ - constexpr和const之间的区别

c++ - 使用 nonfree/feature2d.hpp 的 OpenCV 编译错误

c++ - 通过类的模板参数特化成员模板结构

c++ - 如何从可变模板参数的嵌套类派生?

c++ - 在映射最小值和最大值时从无符号转换为有符号的最佳方法?

c++ - C++ 中 "using"关键字背后的逻辑是什么?