如何确定C++11成员函数的返回类型

bweufnob  于 2023-05-30  发布在  其他
关注(0)|答案(4)|浏览(356)

我试图确定各种C++成员函数的返回类型。我知道decltype和std::declval可以用来做这件事,但我在语法和找到有用的例子方面遇到了问题。下面的TestCBClass显示了一个dumb类的例子,它包含静态和普通成员函数的混合体-有&没有参数和返回类型。根据所讨论的方法,我希望能够从每个方法中声明一个返回类型的向量。
在我的应用程序中,这些方法是std::async的回调,我需要一个std::future<return types>的向量。我尝试过各种声明,比如decltype(std::declval(TestCBClass::testStaticMethod))(我不确定是否需要在方法名前加上&)。这种语法是不正确的--当然它不能编译,但我认为这是应该使用的方法。

class TestCBClass {
public:
    TestCBClass(const int& rValue = 1)
        : mValue(rValue) {
        std::cout << "~TestCBClass()" << std::endl;
    }
    virtual ~TestCBClass() {
        std::cout << "~TestCBClass()" << std::endl;
    }
    void testCBEmpty(void) {
        std::cout << "testCBEmpty()" << std::endl;
    }
    int testCBArgRet(const int& rArg) {
        std::cout << "testCBArgRet(" << rArg << ")" << std::endl;
        mValue = rArg;
    }
    static void testCBEmptyStatic(void) {
        std::cout << "testCBEmptyStatic()" << std::endl;
    }
    static void cbArgRetStatic(const SLDBConfigParams& rParams) {
        std::lock_guard<std::mutex> lock(gMutexGuard);
        std::cout << rParams.mPriority << std::endl;
    }
    static std::string testStaticMethod(const PriorityLevel& rPrty) {
        return "this is a silly return string";
    }
private:
    int mValue;
};
cunj1qz1

cunj1qz11#

如果你更喜欢列出参数类型而不是对应的虚拟值,你也可以使用std::result_ofdecltype,像这样:

#include <iostream>
#include <utility>
#include <type_traits>

struct foo {
  int    memfun1(int a) const { return a;   }
  double memfun2(double b) const { return b; }
};

int main() {
  std::result_of<decltype(&foo::memfun1)(foo, int)>::type i = 10;
  std::cout << i << std::endl;
  std::result_of<decltype(&foo::memfun2)(foo, double)>::type d = 12.9;
  std::cout << d << std::endl;
}

DEMO here.

91zkwejq

91zkwejq2#

  • 如何确定C++11成员函数的返回类型?*
    回答:

你可以使用decltypestd::declval,就像下面的玩具示例:

#include <iostream>
#include <utility>

struct foo {
  int    memfun1(int a) const { return a;   }
  double memfun2(double b) const { return b; }
};

int main() {
  decltype(std::declval<foo>().memfun1(1)) i = 10;
  std::cout << i << std::endl;
  decltype(std::declval<foo>().memfun2(10.0)) d = 12.9;
  std::cout << d << std::endl;
}

LIVE DEMO

toiithl6

toiithl63#

  • 我尝试了各种声明,如decltype(std::declval(TestCBClass::testStaticMethod))*

不必使用std::declval并传递 * 实际参数 *,甚至不需要 * 它们的类型 *,只是为了知道静态/非静态成员函数的返回类型是什么。相反,你可以编写自己的trait来了解给定函数的返回类型:

template <typename T>
struct return_type;
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...) 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...) const volatile> { using type = R; };
template <typename T>
using return_type_t = typename return_type<T>::type;

...

TestCBClass t;

std::future<return_type_t<decltype(&TestCBClass::testCBArgRet)>> a =
        std::async(&TestCBClass::testCBArgRet, t, 1);

std::future<return_type_t<decltype(&TestCBClass::testCBEmpty)>> b =
        std::async(&TestCBClass::testCBEmpty, t);

std::future<return_type_t<decltype(&TestCBClass::testCBEmptyStatic)>> c =
        std::async(&TestCBClass::testCBEmptyStatic);

DEMO

inkz8wg9

inkz8wg94#

编译时推导返回类型**的最新语法如下:

std::invoke_result_t<decltype(&Presenter::present), Presenter, QSqlQuery &> someVariable;

让我们考虑一个例子,你想用默认值构造一个对象,例如。QVector<int>(),但是你需要从模板参数推导出这个类型,在我们的例子中是模板参数Presenter,我们需要推导出一个带有一个参数Presenter::present(QSqlQuery &)的类方法的返回类型:

template<typename Presenter>
inline auto defaultReturnValue() const
{
    return std::invoke_result_t<decltype(&Presenter::present), Presenter, QSqlQuery &>();
}

上面的代码推导了这个类的返回类型:

class VectorPresenter final
{
public:
    QVector<int> present(QSqlQuery &query) const;
};

最后,您将致电:

const auto defaultValue = defaultReturnValue<VectorPresenter>();

结果将是defaultValue变量中的QVector<int>示例。现在,您可以创建一个presenter类,它将返回any类型,并且您将能够推导出此类型。🚀✨

相关问题