Jar*_*ock 11 c++ clang return-type-deduction
以下程序产生编译错误clang,但它传递给其他编译器:
#include <utility>
struct foo
{
auto bar() -> decltype(0)
{
return 0;
}
using bar_type = decltype(std::declval<foo>().bar());
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
这个程序是非法的,如果是的话,有没有正确的方法来定义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
Run Code Online (Sandbox Code Playgroud)
我不确定这是否是无效代码,因为允许不完整的类型declval,并且decltype不评估表达式.
rightføld在他的回答中解释了为什么这段代码无效.
你可以使用std :: result_of:
using bar_type = std::result_of<decltype(&foo::bar)(foo)>::type;
Run Code Online (Sandbox Code Playgroud)
这实际上是这样实现的:
using bar_type = decltype((std::declval<foo>().*std::declval<decltype(&foo::bar)>())());
Run Code Online (Sandbox Code Playgroud)
它与问题中的代码之间的区别在于使用指向成员的operator(.*)而不是成员访问operator(.),并且它不需要完成类型,这由以下代码演示:
#include <utility>
struct foo;
int main() {
int (foo::*pbar)();
using bar_type = decltype((std::declval<foo>().*pbar)());
}
Run Code Online (Sandbox Code Playgroud)
§7.1.6.2说:
对于表达式
e,表示的类型decltype(e)定义如下:
- if
e是未加密码的id-expression或未加括号的类成员访问(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()是不正确的,所以铿锵是正确的.
| 归档时间: |
|
| 查看次数: |
1948 次 |
| 最近记录: |