разрешение перегрузки для шаблонных функций с параметрами не шаблонного типа - PullRequest
0 голосов
/ 18 мая 2018
#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*.Цель состоит в том, чтобы иметь одну перегрузку, которая не фильтрует и не выводит входные данные, а только в том случае, если это ссылка lvalue (а не значение, связанное с const &), и другая перегрузка, которая выполняет фильтрацию и возвращает копию.

1 Ответ

0 голосов
/ 18 мая 2018

Существует ли способ автоматического предпочтения первой перегрузки шаблона, когда аргументы типа 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; });
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...