如何访问模板参数的成员?“成员访问不完整的类型”
How to access the member of a template parameter's? "Member access to incomplete type"
我正在尝试声明一个" lambdas"类,该类将向其他类"测试"提供lambdas(及其类型信息(。Lambdas还将"此"引用到Lambdas内部的混凝土测试实例,以访问测试公共成员。我这样做是为了一次定义lambdas,然后通过dectType((推导其他任何地方的类型但是我会遇到错误:成员访问不完整类型:
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(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
的偏移(,但是,在获得整个定义之前,它可能无法知道特定成员的偏移,因为编译器必须知道您的结构/类的对齐方式(我什至猜测,计算计算时可能涉及一些不直发的逻辑在所有成员知识之后,会员之间的填充,请参见这一点,这完全是编译器和平台。
所以回到您的问题。您告诉编译器将Test3
定义为genLambda1
为会员,这是必须知道成员testVar
的偏移的lambda。似乎很容易,对吧?但是testVar
的偏移取决于整个Test3
的定义(请参阅上面的段落( - 我们在循环中。
您会说:"嘿,愚蠢的编译器,我只给指针指向lambda,而不是按价值副本,您必须知道`test3的整体尺寸,为什么要阻止我这样做?"一个合法的问题,因为从理论上讲,编译器可以稍后解决偏移,但似乎编译器不够聪明。标准说:
lambda-expression的化合物陈述产生了功能呼叫操作员的功能体(8.4(...
基本上说兰伯达体是功能主体,但是在功能主体中,您不能拥有不完整的类型吗?Lambdas对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++?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问
- 为什么类成员数据必须是静态的才能被模板化类的模板化结构成员访问
- 为什么c++允许成员函数定义中实例的私有成员访问
- C/C++ 包含点的宏参数(成员访问运算符)
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 内部类私有成员访问和封闭的友好性
- 通过 C++ 中的另一个结构成员访问结构
- 具体化 PRVALUES 成员访问的 decltype 行为不正确
- 常量表达式中的静态成员访问
- XVALUE来自类成员访问表达式
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 在 c++ 中,为什么 -> 被称为二进制中缀指针成员访问运算符?
- 如何访问模板参数的成员?“成员访问不完整的类型”
- 不明确的可变参数类成员访问
- C 受保护的成员访问
- 将typeID转换为静态成员访问(C )的命名空间