访问方法的返回类型

Accessing the return type of a method

本文关键字:返回类型 方法 访问      更新时间:2023-10-16

我很难做到这一简单的事情。

我发现有效的一件事:

#include <type_traits>
struct A
{
    int Method();
};
static_assert(  std::is_same_v<
        decltype(A{}.Method()), int
    >
); // pass. cool.

好吧。但不是;不是很好。因为我现在有一个默认的可构造要求,并且我需要用所有参数编写呼叫表达式。谁知道它们!

考虑真实情况:

struct A
{
    int Method(MysteriousArgumentsIDontCareAboutAndCanChangeInTheFuture);
};
static_assert(  std::is_same_v<
        decltype(A{}.Method()), int
    >
);  // not so cool anymore (too few arguments to function call, expected 1, have 0)

使用std::invoke_result

怎么样
static_assert(  std::is_same_v<
        std::invoke_result_t< A::Method >, int
    >
);

nah。

呼叫非静态成员函数而没有对象参数

msvc说

非标准语法;使用'&amp;'创建指向会员的指针

我可以摆弄我想要的所有表达式,没有任何好处。
例如:

using T = std::invoke_result_t< decltype(&A::Method) >;

错误:没有类型命名为std :: Invoke_result

如果我删除decltype,则是类型值不匹配(当然)等...

cppreference.com提到了C 14版本的用法:

std::result_of<decltype(&C::Func)(C, char, int&)>::type

并不比我的第一次尝试好得多。所有的论点仍然存在。
在我们的简单情况下,在行动中:https://godbolt.org/z/ktqbth

帮助?

您可以使用Piotr Skotnicki建议的特征:

template <typename T>
struct return_type;
template <typename R, typename... Args>
struct return_type<R(Args...)> { using type = R; };
template <typename R, typename... Args>
struct return_type<R(*)(Args...)> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...)> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) &> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) &&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) const> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) const&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) const&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) volatile> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) volatile&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) volatile&&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) const volatile> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) const volatile&> { using type = R; };
template <typename R, typename C, typename... Args>
struct return_type<R(C::*)(Args...) const volatile&&> { using type = R; };
template <typename T>
using return_type_t = typename return_type<T>::type;

现在您可以做:

static_assert(std::is_same_v<return_type_t<decltype(&A::Method)>, int>);
[static_assert( std::is_same_v< decltype(std::declval<A>().Method()), int >);//super cool now][1]