问题描述
编辑:我忘记了回调函数“捕获”了this
的{{1}}指针。
我正在尝试初始化一些类及其成员。
该类没有没有模板化。
已为其成员 建立模板。它通过模板采用“函数类型”来从封装类中进行回调。 (我不能使用outer
,因为这是时间紧迫的代码。)
此外,我希望编译器可以推断出回叫对象的模板类型(给成员)。
代码看起来像这样(假设所有样板都存在):
std::function
第一次尝试
我不确定为什么它不起作用。我猜想在这种类型的初始化中(在类定义中包含),编译器不会猜测模板类型。也许是因为它使用了聚合初始化(true ?,如果是,为什么不聚合初始化支持模板类型推导)
第二次尝试
这不起作用,因为在定义时未提供模板参数。仅在构造函数中会调用它(在运行时),因此无法进行模板类型推断。
第三次尝试
不能用template<typename func_t>
class inner : public inner_abstract_base
{
public:
func_t m_cb;
inner(func_t cb):m_cb(cb){}
};
class outer
{
Int member_fun(int);
public:
/*********first try****************/
// inner member{[this]{return this->member_fun(123);}}
/*********second try***************/
// inner member;
// outer():member([this]{return this->member_fun(321);})
// {}
/*********third try****************/
// auto lamb = [this]{return this->member_fun(987);};
//This or in the constructor initialization list
// inner<decltype(lamb)> member{lamb};
/*********fourth try***************/
// friend int func();
// inner<decltype(func)> member{func};
/*********fifth try***************/
// std::unique_ptr<inner_abstract_base> member_p;
// outer():member_p([]{return 666;})
// {}
/*********sixth try***************/
// inner<decltype(some_free_func)> member{some_free_func};
};
声明非静态成员(为什么?)-因此,不能首先初始化成员auto
。
第四次尝试
我不喜欢这种方法,因为它比原始设计更进一步,但是-由于某些我无法理解的原因,它无法正常工作。
第五次尝试
这太过分了。我认为这是行不通的,因为我使用不正确。可能是因为我没有将其强制转换为子类型进行分配...(如何?)。甚至在使用“正确”用法的情况下,类型推断可能也不适用于带有指针的设备。
第六次尝试
只是为了娱乐-免费娱乐!由于相同的原因,朋友功能不起作用(合理)而无法正常工作。
底行
如何通过捕获/不捕获lamb
指针来解决这一惨败?
如何让编译器推断成员变量的类型?
或更确切地说是给定的情况下
*抱歉,来回进行编辑...
解决方法
推断成员变量类型
在C ++中是不可能的。无法推断成员变量类型。
- 我不确定为什么它不起作用。
首先不起作用,因为您未指定成员类型的模板参数,因此无法推论得出。
...可能是因为它使用了聚合初始化
不是。
- 非静态成员不能用auto声明(为什么?)
因为auto需要类型推导,而成员变量的类型却不推导。
- 由于某种我无法理解的原因而无法正常工作。
它不起作用的原因之一是因为您尝试将函数类型指定为模板参数,并且内部类不能具有函数类型的成员变量。由于名称查找问题,此操作似乎在此之前失败。
- 我认为这是行不通的,因为我使用不正确。
您尝试使用lambda参数初始化唯一的指针。唯一指针根本没有让构造函数接受此类参数。
您如何解决这一惨败?
一种方法:不要尝试定义成员变量。例如,使用成员函数:
constexpr auto member_fun()
{
return inner{[]{return 123;}};
}
由于您的lambda没有内部状态,因此函数指针也将起作用:
using fun = int();
inner<fun*> member{[]{return 123;}};
这可能比函数替代方案更难优化,因为通常不容易证明函数指针未更改。而且const成员有问题。
,您的表示法有些怪异,但最接近的是第3次尝试。对其进行稍作更改即可得到:
int lamb() { return 50; }
template<typename func_t>
class inner
{
public:
func_t m_cb;
inner(func_t cb):m_cb(cb){}
};
class outer
{
public:
inner<decltype(&lamb)> member{lamb};
};
int main()
{
outer o;
}
请注意,您尝试使用decltype(lamb)
时遇到的问题是它为您提供了函数类型,即在我的情况下它扩展为int()
,并且您无法声明该类型的变量。但是您知道可以声明什么的变量吗?是的,一个函数指针,即decltype(&lamb)
!
或者,您可以将原始decltype(lamb)
放在function<>
对象中,然后由自动转换接管:
#include <functional>
int lamb() { return 50; }
template<typename func_t>
class inner
{
public:
std::function<func_t> m_cb;
inner(func_t cb):m_cb(cb){}
};
class outer
{
public:
inner<decltype(lamb)> member{lamb};
};
int main()
{
outer o;
}