如何从类中获取成员函数的返回类型
How to get the return type of a member function from within a class?
以下程序使用clang
产生编译错误,尽管它会传递给其他编译器:
#include <utility>
struct foo
{
auto bar() -> decltype(0)
{
return 0;
}
using bar_type = decltype(std::declval<foo>().bar());
};
int main()
{
return 0;
}
clang
产量:
$ clang -std=c++11 clang_repro.cpp
clang_repro.cpp:10:48: error: member access into incomplete type 'foo'
using bar_type = decltype(std::declval<foo>().bar());
^
clang_repro.cpp:3:8: note: definition of 'foo' is not complete until the closing '}'
struct foo
^
1 error generated.
这个程序是非法的吗?如果是,有没有正确的方法来定义foo::bar_type
?
clang
详细信息:
$ clang --version
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
Thread model: posix
g++4.9发布相同错误
我不确定这是否是一个无效的代码,因为
declval
允许不完整的类型,并且decltype
中的表达式不会被求值
rightføld在他的回答中很好地解释了为什么这个代码是无效的。
您可以使用std::result_of:
using bar_type = std::result_of<decltype(&foo::bar)(foo)>::type;
它实际上是这样实现的:
using bar_type = decltype((std::declval<foo>().*std::declval<decltype(&foo::bar)>())());
这与问题中的代码的区别在于,使用了指向成员运算符(.*
)的指针,而不是成员访问运算符(.
),并且它不需要类型完整,这一点可以通过以下代码来证明:
#include <utility>
struct foo;
int main() {
int (foo::*pbar)();
using bar_type = decltype((std::declval<foo>().*pbar)());
}
§7.1.6.2说:
对于表达式
e
,由decltype(e)
表示的类型定义如下:
- 如果
e
是未加括号的id表达式或未加括号类成员访问(5.2.5),则decltype(e)
是由e
命名的实体的类型
§5.2.5规定:
对于第一个选项(点),第一个表达式应具有完整的类类型…
§9.2规定:
在类说明符的结束
}
处,类被视为完全定义的对象类型(3.9)(或完整类型)…
decltype(std::declval<foo>().bar())
(进而std::declval<foo>().bar()
)出现在闭合的}
之前,所以foo
是不完整的,所以std::declval<foo>().bar()
是不成形的,所以clang是正确的。
相关文章:
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法