推断成员变量类型

问题描述

编辑:我忘记了回调函数“捕获”了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 ++中是不可能的。无法推断成员变量类型。


  1. 我不确定为什么它不起作用。

首先不起作用,因为您未指定成员类型的模板参数,因此无法推论得出。

...可能是因为它使用了聚合初始化

不是。

  1. 非静态成员不能用auto声明(为什么?)

因为auto需要类型推导,而成员变量的类型却不推导。

  1. 由于某种我无法理解的原因而无法正常工作。

它不起作用的原因之一是因为您尝试将函数类型指定为模板参数,并且内部类不能具有函数类型的成员变量。由于名称查找问题,此操作似乎在此之前失败。

  1. 我认为这是行不通的,因为我使用不正确。

您尝试使用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;
}