获取没有对象的成员函数的返回类型

Jam*_*mes 37 c++ templates decltype c++11

我有一些我无法修改的课程.每个都有一个复制构造函数,至少一个其他构造函数,以及一个foo()返回一些值的函数.我想创建一个可以从这些类中派生出来的类模板,并且有一个与返回类型相同类型的数据成员foo()(抱歉,如果我的某些术语有误).

换句话说,我想要一个类模板

template<typename T> class C : public T
{
  footype fooresult;
};
Run Code Online (Sandbox Code Playgroud)

footype返回类型在哪里T::foo().

如果基类都有一个默认的构造函数,我可以这样做

decltype(T().foo()) fooresult;
Run Code Online (Sandbox Code Playgroud)

(使用GCC中的C++ 0x功能)但除了复制构造函数之外,这些类没有任何特定的构造函数.

GCC也不允许decltype(this->foo()),虽然显然有可能将其添加到C++ 0x标准 - 有谁知道这有多大可能性?

我觉得应该可以做某些事情decltype(foo())或者decltype(T::foo())那些似乎不起作用的东西:GCC给出了表格的错误cannot call member function 'int A::foo()' without object.

当然,我可以有一个额外的模板参数footype,甚至是类型的非类参数T,但有没有办法避免这种情况?

Pup*_*ppy 60

你不需要 - 记住,因为decltype不评估它的参数,你可以只是调用nullptr.

decltype(((T*)nullptr)->foo()) footype;
Run Code Online (Sandbox Code Playgroud)


How*_*ant 40

另一种选择是:

#include <utility>

template<typename T> class C : public T
{
   decltype(std::declval<T>().foo()) footype;
};
Run Code Online (Sandbox Code Playgroud)

declval返回一个T&&.或者,如果foo可能会被rvalue-ref限定符重载,并且您希望确保获得foo的左值重载:

   decltype(std::declval<T&>().foo()) footype;
Run Code Online (Sandbox Code Playgroud)

在这个例子中declval返回一个T&.

((T*)nullptr)->解决方案一样,std::declval对类型没有任何要求T.


sig*_*gma 8

也可以使用 C++17std::invoke_resultstd::result_of它所替换的已弃用的来执行此操作:

#include <type_traits>

template<typename T> class C : public T
{
    using footype = std::invoke_result_t<decltype(&T::foo), T>;
    footype fooresult;
};
Run Code Online (Sandbox Code Playgroud)