Вызвать менее ограниченную функционально эквивалентную функцию - PullRequest
2 голосов
/ 12 апреля 2020

Рассмотрим следующий код:

#include <iostream>
#include <type_traits>

struct A;

template<class T>
concept HasParent = std::is_convertible_v<typename T::parent*, A*>;

struct A{};

struct B : A { using parent = A; };

template<class T>       int foo(T*) { return 1; }

template<HasParent T>   int foo(T*)
{
  // call the other one?
  return 2;
}

int main()
{
  B b;
  std::cout << foo(&b) << std::endl; // displays 2
  return 0;
}

Можно ли вызвать общую функцию foo<T>(T*) из foo<HasParent T>(T*)?

(это (функциональный) пример , но я могу связать полный код на github)

1 Ответ

1 голос
/ 12 апреля 2020

Можно ли вызвать общую функцию foo<T>(T*) из foo<HasParent T>(T*)?

Вам необходим какой-то способ различения двух функций, чтобы сделайте это.

Например:

template <typename T>               void foo(T);
template <typename T> requires true auto foo(T) -> int;

Второй явно более ограничен, чем первый, для всех T, поэтому foo(42) вызывает второе. Но вы можете различать два:

auto unconstrained = static_cast<void(*)(int)>(foo);

Здесь шаблон функции-ограничения возвращает int, поэтому он не является жизнеспособным кандидатом, а вместо этого мы получаем неограниченный.

В вашем примере оба возвращают int, поэтому этот конкретный прием не работает. Но ключ в том, что вам нужен какой-то способ разграничения двух шаблонов.

Возможно, лучший способ:

template <typename T, std::monostate M = {}>
void foo(T);

template <typename T> requires true
void foo(T arg) {
    foo<T, std::monostate{}>(arg); // calls the unconstrained one
}

Использование monostate здесь довольно мило, поскольку на самом деле это не меняет количество экземпляров шаблона (есть только один monostate .. .) foo(42) вызывает второе, которое вызывает первое. Demo .

Но, возможно, было бы лучше просто добавить новую функцию и заставить как неограниченную, так и ограниченную версию шаблона функции вызывать эту функцию (в том смысле, что она, вероятно, менее крипти c чем monostate подход).

...