18

以下代码:

struct A
{
    int f(int);
    auto g(int x) -> decltype(f(x));
};

编译失败,报错:

error: cannot call member function 'int B::f(int)' without object

如果我将其更改为:

struct A
{
    int f(int);
    auto g(int x) -> decltype(this->f(x));
};

我得到另一个错误:

error: invalid use of 'this' at top level

这些有什么问题?我正在使用 gcc 4.6

4

6 回答 6

14

以下是神奇的词:

struct A
{
    int f(int);
    auto g(int x) -> decltype((((A*)0) ->* &A::f)(x)) ;
};

编辑我从 Mikael Persson 的回答中看到,这是在 boost 中完成的。

于 2011-02-28T23:06:35.283 回答
7

result_of 和 decltype 组合可以给出成员函数的返回类型

#include <type_traits>
using namespace std;

struct A
{
    int f(int i) { return i; } 
    auto g(int x) -> std::result_of<decltype(&A::f)(A, int)>::type
    { 
        return x;
    }
};


int main() {
    A a;
static_assert(std::is_same<decltype(a.f(123)), 
                  decltype(a.g(123))>::value, 
                  "should be identical");
return 0;
}
于 2014-04-30T22:37:19.297 回答
6

目前你只能在函数体内访问“this”和类的成员但这很可能很快就会改变:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1207

于 2011-03-01T19:24:50.080 回答
5

Comeau不喜欢auto作为顶级返回类型,但以下编译成功:

template <typename R, typename C, typename A1> R get_return_type(R (C::*)(A1));

struct A
{
    int f(int);
    decltype(get_return_type(&A::f)) g(int x);
};

基本上,你必须声明至少一个额外的构造来获得你想要的类型。并decltype直接使用。

编辑:顺便说一句,这也适用于深入研究成员函数的返回类型:

template <typename R, typename C, typename A1> R get_return_type(R (C::*)(A1));

struct B { int f(int); };

struct A
{
    int f(int);
    B h(int);

    decltype(get_return_type(&A::f)) g(int x);

    decltype(get_return_type(&A::h).f(0)) k(int x);
};

int main()
{
    return A().k(0);
}

诚然,它没有 . 那样的便利auto f()-> ...,但至少它可以编译。

于 2011-02-28T22:35:12.417 回答
3

经过一些测试,既不decltype(declval<A>().f(x))也不decltype(((A*)0)->f(x))行。

但是,似乎使用 boost::bind 会起作用(而且它是“幕后”版本):

struct A
{
    int f(int);
    auto g(int x) -> decltype(boost::bind(&A::f,0,x)());
    auto h(int x) -> decltype((((A*)0)->*(&A::f))(x)); //similarly (what Boost.Bind does under-the-hood.
};

当然,这并不漂亮。我想你可以看看 boost::bind 是如何做到的,也许会找到一个更好的解决方案。

编辑

正如 MSN 建议的那样,您还可以制作自己的函数模板来解决此问题:

template< typename R, typename C, typename... Args > R member_func(R (C::*)(Args...)); 

struct A
{
    int f(int);
    auto g(int x) -> decltype(member_func(&A::f));
};
于 2011-02-28T21:03:27.263 回答
0

在我看来,这不起作用,因为 decltype 在方法之外,而 A 在那一刻是一个不完整的类型(所以你甚至不能这样做A().f(x))。

但你不应该真的需要那个。在 A 的声明之外,这将按预期工作,在 A 中,您应该知道上面几行声明的函数的返回类型。或者你可以写:

struct A {
    typedef int ret_type;
    ret_type f(int x);
    ret_type g(int x);
};

这甚至适用于普通的 c++03。

于 2011-02-28T22:30:38.600 回答