问题
I am trying to determine the return type of a various C++ member functions. I understand that decltype and std::declval can be used to do this, but I am having problems with the syntax and finding useful examples. The TestCBClass
below shows an example of a dumb class that contains a mixture static and normal member functions - with & without arguments and return types. Depending on the method in question, I would like to be able to declare a vector of return types from each of the various methods.
In my application, these methods are callbacks for std::async
and I need a vector of std::future<return types>
. I've tried various declarations such as decltype(std::declval(TestCBClass::testStaticMethod))
(I'm not sure if I need an &
before the method name). This syntax is incorrect - and of course it does not compile, but I think its the approach that should be used.
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;
};
回答1:
You may also use std::result_of
and decltype
, if you prefer to list arguments types rather than the corresponding dummy values, like this:
#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.
回答2:
How can I determine the return type of a C++11 member function?
Answer:
You could use decltype
and std::declval
like the toy example below:
#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
回答3:
I've tried various declarations such as decltype(std::declval(TestCBClass::testStaticMethod))
You don't have to use std::declval
and pass actual arguments, not even their types, just to know what is the return type of a static/non-static member function. Instead, you can write your own trait to know what is the return type of a given function:
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
来源:https://stackoverflow.com/questions/26107041/how-can-i-determine-the-return-type-of-a-c11-member-function