How can I determine the return type of a C++11 member function

后端 未结 4 1102
心在旅途
心在旅途 2021-02-19 20:39

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

相关标签:
4条回答
  • 2021-02-19 21:05

    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

    0 讨论(0)
  • 2021-02-19 21:07

    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.

    0 讨论(0)
  • 2021-02-19 21:08

    Latest syntax to deduce return type at compile time is like this:

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

    Let's consider an example, that you want to construct an object with a default value, eg. QVector<int>(), but you need to deduce this type from template parameter, in our example is template parameter Presenter and we need to deduce return type for a class method with one parameter Presenter::present(QSqlQuery &):

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

    The above code deduces the return type for this class:

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

    Finally, you will call:

    const auto defaultValue = defaultReturnValue<VectorPresenter>();
    

    The result will be that you will have QVector<int> instance in defaultValue variable. And now, you can create a presenter class, which will return any type and you will be able to return the default value for this type.

    0 讨论(0)
  • 2021-02-19 21:15

    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

    0 讨论(0)
提交回复
热议问题