2014-09-29 67 views
5

我試圖確定各種C++成員函數的返回類型。我明白,decltype和std :: declval可以用來做到這一點,但我遇到了語法問題並找到了有用的例子。下面的TestCBClass顯示了一個包含混合靜態和常規成員函數的啞類的示例 - 帶有無參數和返回類型的&。根據所討論的方法,我希望能夠從各種方法中聲明一個返回類型的向量。如何確定C++ 11成員函數的返回類型

在我的應用程序中,這些方法是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; 
}; 

回答

5

你也可以使用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.

+0

非常好,簡單!謝謝 – johnco3 2014-09-29 20:31:18

3

如何確定一個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

+0

謝謝,會發生什麼,如果memfun1()或memfun2 T() ake參數 - 在我的情況下,我的testStaticMethod需要一個PriorityLevel對象 - 這不是默認的可構造的 - 我認爲這是什麼declval是正確的?還有一件事,我忘了問我的問題 - 是否可以打印出類型爲字符串? – johnco3 2014-09-29 19:18:54

+0

@ johnco3你只需要輸入一些虛擬輸入參數。我編輯了答案。 – 101010 2014-09-29 19:22:41

+0

@ johnco3 Yeap'declval'確保對象的構造函數不會被引發。你可以使用['typeid'](http://en.cppreference.com/w/cpp/language/typeid)來獲得一個類型的字符串。更好的方法是使用'type_traits',特別是['std :: is_same'](http://en.cppreference.com/w/cpp/types/is_same)來檢查一個類型是否與另一個類型相同。 – 101010 2014-09-29 19:26:18

4

我已經嘗試了各種宣言,如decltype (性病:: 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); 

DEMO

+0

非常好 - 它工作(天知道爲什麼;))類型特徵不是我的東西 - 雖然std :: result_of似乎更簡單和更容易使用模板機器全部隱藏在封面下。檢查答案是有用的 – johnco3 2014-09-29 20:30:27

+0

@ johnco3:如果你喜歡重複函數參數的類型,每次你聲明'std :: future',那麼是的,你可以使用'std :: result_of' – 2014-09-29 20:34:52

相關問題