- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试声明一个类“Lambdas”,它将向另一个类“Test”提供 lambda(及其类型信息)。 Lambdas 还在 lambdas 内部持有对具体测试实例的“this”引用,用于访问测试公共(public)成员。我这样做是为了定义一次 lambda,然后通过 decltype() 在其他任何地方推导类型但我收到错误:成员访问不完整类型:
template <typename T>
struct LambdasInstances {
T * self;
explicit LambdasInstances(T * p) : self(p) {} // CAPTURE Test "this"
auto genLambda1() {
return [=](int x){
self->testVar; // ERROR: Member access to incomplete type
};
}
};
class Test3 {
public:
LambdasInstances<Test3> instances;
int testVar;
Test3() : instances(this) {}
decltype(instances.genLambda1()) varLambda = instances.genLambda1();
void useLambda() { varLambda(123); }
};
但是如果我要在外部定义 genLambda(),那么我会遇到另一个问题 - 错误:在其定义之前不能使用具有推导类型的 genLambda()!:
template <typename T>
struct LambdasInstances {
T * self;
explicit LambdasInstances(T * p) : self(p) {}
auto genLambda1(); // would be defined after Test3 declaration
};
class Test3 {
public:
int testVar;
LambdasInstances<Test3> instances;
Test3() : instances(this) {}
decltype(instances.genLambda1()) varLambda = instances.genLambda1();
};
// IF WE DEFINE AFTER :: ^ genLambda() with deduced type cannot be used before its defined!
template< typename T>
auto LambdasInstances<T>::genLambda1() {
return [=](int x){
self->testVar;
};
}
最佳答案
编译器可能需要整个可用类型的定义才能知道成员的偏移量(例如,在表达式 self->testVar
中,编译器必须知道 testVar
), 但它可能无法知道特定成员的偏移量,直到它获得整个定义,因为编译器必须知道你的结构/类的对齐方式(我什至猜测一些在计算成员之间的填充时可能涉及不直接的逻辑)在所有成员都知道之后,请参阅 this ,这完全是特定于编译器和平台的。
回到你的问题。您告诉编译器以 genLambda1
作为成员来定义 Test3
,这是一个必须知道成员 testVar
的偏移量的 lambda。看起来很容易,对吧?但是 testVar
的偏移量取决于整个 Test3
的定义(请参阅上面的段落)- 这里我们处于循环中。
你会说:“嘿愚蠢的编译器,我只给出了一个指向 lambda 的指针,而不是一个你必须知道 `Test3 的整个大小的按值复制,你为什么要阻止我这样做?”。这是一个合理的问题,因为理论上编译器可以稍后解析偏移量,但似乎编译器不够聪明。标准说:
The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator ...
这基本上是说 lambda 主体是函数主体,但在函数主体中你不能有不完整的类型,对吧? Lambda 对 C++ 来说相对较新,并没有详细说明所有的极端情况,所以我们希望在未来某个时候这个问题会得到解决,当然编译器会比标准更复杂。
对于您的问题,我看到了以下解决方案:
template <typename T>
struct LambdasInstances {
explicit LambdasInstances(T* p) : _lambda([=](int x) { return p->testVar; }) {}
auto genLambda1() { return _lambda; }
private:
std::function<void(int)> _lambda;
};
class Test3 {
public:
int testVar;
LambdasInstances<Test3> instances;
Test3() : instances(this) {}
decltype(instances.genLambda1()) varLambda = instances.genLambda1();
};
int main() {
Test3 test3;
Test3* test3_ptr;
LambdasInstances<Test3> instances(&test3);
auto lambda = [=](int x) { return test3_ptr->testVar; };
std::function<void(int)> functor = lambda;
cerr << sizeof(Test3) << endl;
cerr << sizeof(LambdasInstances<Test3>) << endl;
cerr << sizeof(lambda) << endl;
cerr << sizeof(functor) << endl;
return 0;
}
不同之处在于,std::function
为您提供了一个抽象级别,可以保护 LambdasInstances::genLambda1
类型不受 Test3
定义的影响>。不幸的是,正如您将从 main
输出中看到的那样,该函数比 lambda 占用更多的内存。如果这不能满足您的需求,我建议您修改设计,也许您会在 lambdas 时代之前的旧好技术中找到一些东西。
关于c++ - 如何访问模板参数的成员? "Member access to incomplete type",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44345233/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!