具有非模板类型参数的模板函数的重载解析

时间:2018-05-18 09:34:06

标签: c++ templates c++14 overloading sfinae

#include <type_traits>
#include <vector>
#include <iostream>

namespace detail
{
template <typename T, typename U>
constexpr bool is_lvalue_reference_of_type =
    std::is_lvalue_reference<T>::value && std::is_same<std::decay_t<T>, U>::value;

// container is lvalue reference and no filter, echo back parameter
template <typename Container,
          typename = std::enable_if_t<
                is_lvalue_reference_of_type<Container, std::vector<int>>
            >
          >
const std::vector<int>& f(void *, Container && c)
{
    std::cout << "void *\n";
    return c;
}
// filter input and return a copy
template <typename Filter,
          typename = std::enable_if_t<!std::is_same_v<std::decay_t<Filter>, void *>>>
std::vector<int> f(Filter &&, const std::vector<int> &)
{
    std::cout << "Filter \n";
    return {};
}
}


template <typename T = void*>
void g(T && t = nullptr)
{
    const std::vector<int> v;
    detail::f(std::forward<T>(t), v);
}

int main(int, const char * const * const)
{
    g();
    g([](const int) {return true;});
}

当传递 void*const std::vector<int> & 类型的参数而没有手动排除第二个模板时,是否有一种方法可以自动首选模板重载这种组合超负荷?我发现手动禁用第二个重载是多余的,因为第一个重载已经将非模板类型的第一个参数指定为 void* 。目标是让一个重载没有过滤并回显输入,但只有当它是左值引用(不是绑定到const &的右值)和另一个重载进行过滤并返回副本。

1 个答案:

答案 0 :(得分:1)

  

当传递 void*const std::vector & 类型的参数而没有手动排除第二个模板时,是否有一种方法可以自动首选模板重载这种组合超负荷?

也许您可以在第一次重载中添加第三个未使用的参数int,在第二次重新添加long,并使用f()0调用int值)优先考虑第一个。

以下是一个完整的例子

#include <vector>
#include <iostream>

namespace detail
 {
   template <typename Container>
   std::vector<int> const & f (void *, Container && c, int)
    { std::cout << "void *\n"; return c; }

   template <typename Filter>
   std::vector<int> f (Filter &&, std::vector<int> const &, long)
    { std::cout << "Filter \n"; return {}; }
 }


template <typename T = void*>
void g (T && t = nullptr)
 {
   std::vector<int> const v;
   detail::f(std::forward<T>(t), v, 0);
 }

int main ()
 {
   g();
   g([](int const) { return true; });
 }