为什么成员函数尝试块处理程序中的 lambda(捕获"this")无法访问 VC++ 2013 中的私有数据成员?
Why can't a lambda (capturing 'this') in a member function-try-block handler access private data members in VC++ 2013?
与静态初始化器的问题不同,但可能与此有关。
在这里,前两个函数可以很好地编译,最后一个函数在vc++中不能编译,但在clang和gcc中可以:
class A {
protected:
std::string protected_member = "yay";
public:
void withNormalBlock();
void withFunctionBlock();
void noLambda();
};
void A::withNormalBlock() {
try {
throw std::exception();
} catch (...) {
[this]() {
std::cout << protected_member << std::endl;
}();
}
}
void A::noLambda() try {
throw std::exception();
} catch (...) {
std::cout << protected_member << std::endl;
}
void A::withFunctionBlock() try {
throw std::exception();
} catch (...) {
[this]() {
// this line is the problem:
std::cout << protected_member << std::endl;
}();
}
- in clang (OK) gcc (OK)
- in vc++ (
error C2248: 'A::protected_member' : cannot access protected member declared in class 'A'
) - vc++ 2015—相同的处理
我在标准中找不到任何建议function-try-block的handler/catch块应该从函数范围中豁免,或者lambda的闭包类型应该改变。如果将访问类型更改为全public,则代码将编译。
根本原因是什么?这是一个bug,还是可以更改编译器设置的特定内容?
我猜这是一个编译器错误。它在VS2015中也会报告相同的错误。奇怪的是,在VS2015
中,显式模拟lambda功能的尝试没有任何问题。class A
{
protected:
std::string protected_member = "yay";
public:
void withFunctionBlock();
};
void A::withFunctionBlock() try
{
throw std::exception();
}
catch (...)
{
struct Closure {
Closure(A *this_) : this_(this_) {}
void operator ()() const { std::cout << this_->protected_member << std::endl; }
A *this_;
};
Closure(this)();
}
我想知道VS c++编译器在底层有什么不同…
似乎这是一个bug, catch
作用域中的lambda是在类作用域之外生成的。我试图用类型来证明这一点,但是Visual Studio的lambda名称被奇怪地弄乱了,名字本身并不能证明任何东西。但是,以下代码段生成的错误代码显示名称不同:
#include <iostream>
#include <typeinfo>
class Foo {
private:
public:
void testLambda()
try {
auto tryScope = [this]() {};
void (*p)() = tryScope;
}
catch(...)
{
auto catchScope = [this]() {};
void (*p)() = catchScope;
}
};
错误输出: (10): error C2440: 'initializing' : cannot convert from 'Foo::testLambda::<lambda_8a3a8afea7359de4568df0e75ead2a56>' to 'void (__cdecl *)(void)'
(15): error C2440: 'initializing' : cannot convert from '<lambda_8cbc08e7748553fb5ae4e39184491e92>' to 'void (__cdecl *)(void)'
相关文章:
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 用于访问容器<T>数据成员的正确 API
- 访问者访问变体并返回不同类型时出错
- 如果使用低于 VS2015 的 vc++ 编译器版本编译,则 DLL 中的访问冲突
- vc++ 访问冲突读取位置
- 访问违规读取位置-opencv/VC++
- cout导致VC++10中的访问冲突
- 跨 VC 解决方案中的多个项目访问同一对象
- 在 VC++ 中访问一个文件中声明的变量.(外部关键字用法)
- 使用 VC++ 中的 Try 和 catch 块捕获内存访问冲突
- 视觉 我们可以在C++/ VC++中访问ODB++文件(PCB)
- VC++ 上的访问冲突错误
- 如何让VC++以2D数组的形式访问指针
- 用vc++函数构建DLL是不可访问的
- 为什么静态初始值设定项中的 lambda 无法访问 VC++2013 中类的私有成员?
- 为什么成员函数尝试块处理程序中的 lambda(捕获"this")无法访问 VC++ 2013 中的私有数据成员?
- 从私有成员值类型 (bool) 读取的 VC++ 访问冲突
- 是否有一种方法来创建一个文件,只有我的应用程序可以访问使用vc++