【问题标题】:overload resolution for template functions with non template type parameters具有非模板类型参数的模板函数的重载决议
【发布时间】:2018-05-18 09:34:05
【问题描述】:
#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&lt;int&gt; &amp; 类型的参数时,是否有一种方法可以自动首选第一个模板重载,而无需手动排除此组合的第二个重载?我发现手动禁用第二个重载是多余的,因为第一个重载已经将非模板类型的第一个参数指定为 void*。目标是让一个重载不过滤并回显输入,但仅当它是左值引用(不是绑定到const &amp; 的右值)和另一个执行过滤并返回副本的重载。

【问题讨论】:

  • 重载决议试图找到一个与 all 参数最匹配的函数。但显然,第一个函数与void* 完全匹配。第二个函数更专门用于第二个参数,并且匹配向量。所以没有最好的选择。

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


【解决方案1】:

在传递 void*const std::vector &amp; 类型的参数时,是否有一种方法可以自动优先使用第一个模板重载,而无需手动排除此组合的第二个重载?

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

下面是一个完整的例子

#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; });
 }

【讨论】:

    猜你喜欢
    • 2018-05-15
    • 1970-01-01
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    相关资源
    最近更新 更多