我有编译器不同意一个小的C++ 14代码片段:
#include <cassert>
struct unmovable {
unmovable() {}
unmovable(unmovable&&) = delete;
};
int main()
{
unmovable u;
auto i = [&]() -> decltype(auto) { return u; };
auto& uu = i();
assert(&uu == &u);
}
Run Code Online (Sandbox Code Playgroud)
该程序被g ++ 4.9.3,g ++ - 5.1.0,g ++ - 5.2.0和VisualStudio 2015接受,但不是由clang ++ - 3.7接受.
clang ++ - 3.7推断返回类型为unmovable(值)而不是unmovable&.
如果程序稍微改变,以便变量u是全局的,那么所有编译器都会同意错误.
据我了解,当变量是本地变量时,ulambda中捕获的应该是类型unmovable&.
我没有C++ 14标准,但希望github的草案是相关的.我的7.1.6.2和7.1.6.4的解释是,decltype(auto)成为decltype(u)从返回,这在全球的情况下应该是unmovable(值),并在当地的拉姆达参考捕获u,它应该成为unmovable&自捕获的变量的类型必须为unmovable& …
这段代码在g ++ 4.9及更高版本(包括从svn current构建时)失败,但是使用clang ++和microsofts编译器(来自VS2015)编译时没有警告.
#include <functional>
struct A {
void operator()() const {}
};
struct B {
void operator()() const {}
};
struct C : private A, private B
{
operator std::function<void()>() const { return nullptr; }
};
int main()
{
std::function<void()> f{C{}};
}
Run Code Online (Sandbox Code Playgroud)
建设f中的main()失败,因为operator()是在结构暧昧C.
为什么g ++认为这是不明确的?函数调用操作符C是私有继承的,不可访问.向void operator()() conststruct 添加私有或显式删除C会使代码编译并按预期使用转换运算符.为什么这些无法访问的运营商在无法访问的继承运营商时不会出现问题?