以下代码:
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
答案 0 :(得分:11)
以下是神奇的词语:
struct A
{
int f(int);
auto g(int x) -> decltype((((A*)0) ->* &A::f)(x)) ;
};
编辑我从Mikael Persson的回答中看到,这就是它在升级中的表现。
答案 1 :(得分: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;
}
答案 2 :(得分:6)
目前您只能访问“this”以及内部功能正文中的成员,但很可能很快就会更改:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1207
答案 3 :(得分: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()-> ...
的便利性,但至少它会编译。
答案 4 :(得分: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));
};
答案 5 :(得分: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。