invoke_result для получения возвращаемого типа функции-члена шаблона

Как я могу получить тип результата функции-члена шаблона?

Следующий минимальный пример иллюстрирует проблему.

#include <type_traits>

template <typename U>
struct A {
};

struct B {
   template <typename F = int>
   A<F> f() { return A<F>{}; }

   using default_return_type = std::invoke_result_t<decltype(f)>;
};

int main()
{
    B::default_return_type x{};

    return 0;
}

Смотрите вживую на Колиру.

Код не компилируется, выдает ошибку:

main.cpp:11:63: ошибка: decltype не удается разрешить адрес перегруженной функции

11 | using default_return_type = std::invoke_result_t;

Каков правильный синтаксис для получения типа B::f с параметром шаблона F установить по умолчанию?

1 ответ

Решение

Вы можете получить возвращаемый тип следующим образом:

using default_return_type = decltype(std::declval<B>().f());

Полный пример:

#include <type_traits>
#include <iostream>
template <typename U>
struct A {
};

struct B {
   template <typename F = int>
   A<F> f() { return A<F>{}; }

   using default_return_type = decltype(std::declval<B>().f());
};

int main()
{
    B::default_return_type x{};
    std::cout << std::is_same< B::default_return_type, A<int>>::value;
}

PS: похоже, что clang и более старые версии gcc не довольны B быть неполным типом и призванием f. В качестве обходного пути перемещениеusing вне класса должно помочь.

Другие вопросы по тегам