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

joh*_*co3 9 c++ decltype c++11

我试图确定各种C++成员函数的返回类型.我知道decltype和std :: declval可用于执行此操作,但我遇到语法问题并找到有用的示例.在TestCBClass下面显示了包含一个混合物静态和正常成员函数哑类的一个例子-具有不与参数和返回值.根据所讨论的方法,我希望能够从各种方法中声明返回类型的向量.

在我的应用程序中,这些方法是回调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;
};
Run Code Online (Sandbox Code Playgroud)

Kri*_*izz 8

您也可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

DEMO在这里.

  • 从 C++17 开始,我们应该使用 [`std::invoke_result` 而不是 `std::result_of`](//en.cppreference.com/w/cpp/types/result_of)。但 [101010 的方式](/a/26107152) 似乎更通用,因为它允许处理重载函数。 (2认同)

101*_*010 6

如何确定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;
}
Run Code Online (Sandbox Code Playgroud)

现场演示


Pio*_*cki 5

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

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

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);
Run Code Online (Sandbox Code Playgroud)

演示