【问题标题】:Declare class member variables inside class member functions在类成员函数中声明类成员变量
【发布时间】:2019-11-01 03:50:08
【问题描述】:

是否有任何技术或编译器扩展关键字在类成员函数中声明类成员变量?类似的东西

struct test_t{
    void operator ()(){
        instance_local int i = 0;
    }
};

我想到的最好的方法是使用thread_local,然后在另一个线程中执行成员函数,但这太丑了,没用。


编辑:示例

对于以下可能令人困惑的示例,我真的很抱歉(它与我昨天的问题Is there any problem in jumping into if(false) block? 有关)。我真的试图减少混乱......

#include <iostream>

#define instance_local thread_local

struct A{
    A(int i) :
        i(i)
    {

    }
    void dosomethinguseful(){
        std::cout << i << std::endl;
    }
    int i;
};
struct task1{
    int part;
    task1() : part(0){}
    void operator ()(){
        int result_of_calculation;
        switch (part) {
        case 0:{
            //DO SOME CALCULATION
            result_of_calculation = 5;
            instance_local A a(result_of_calculation);
            if(false) 
              case 1:{ a.dosomethinguseful();}
            part++;
        }
        default:
            break;
        }
    }
};
int main(){
    task1 t;
    t();
    t();
    return 0;
}

instance_local A a(result_of_calculation); 这就是我可以从这样的关键字中得到的,而不是为a 制作智能指针。

【问题讨论】:

  • 为什么不直接创建一个普通的成员变量?
  • 考虑非阻塞函数包装器,其中某些块在每个函数调用上执行。因此,该函数将被重复调用,直到它完成或成功。如果你这样做,你可能有一个类实例只能在例如之后构造。块 2。所以现在的解决方法是制作智能指针成员变量,但是样板代码加起来了。如果需要,我会举个例子。
  • 是的,我想你需要举个例子。
  • 我希望不会!!你能想象在读取类定义时尝试维护代码不能被依赖来确定类的定义,因为它的一部分可能隐藏在某些函数实现中吗?
  • @ezegoing 你在描述一个协程!它们在 C++20 中。目前,它被实现为一个动态分配的对象,其布局可以由编译器后端确定以进行优化。在 C++17 或更早版本中模拟它的方法是实现一个状态机(你的开关)+一个状态。作为成员,国家会更好

标签: c++


【解决方案1】:

您正在描述一个协程。这是它可能看起来的粗略草图(我不是协程专家)

auto task1() -> some_awaitable_type {
    result_of_calculation = 5;
    A a(result_of_calculation);

    co_yield;

    a.dosomethinguseful();
}

这可以这样调用:

some_awaitable_type maybe_do_something = task1();
// calculation done here

// dosomethinguseful called here
co_await maybe_do_something();

【讨论】:

    【解决方案2】:

    没有。编译器需要知道类的结构,而不需要编译所有的方法实现。如果您可以将instance_local int foo 放入方法体中,那将使数据结构的大小增加 4 个字节。

    在更原则的层面上,隐藏数据并不好。您可能会想到的全局变量(静态局部变量)的等效功能是从 C 中继承而来的,被广泛认为是一种反模式: Why are static variables considered evil?

    【讨论】:

      【解决方案3】:

      不直接,不。

      你可以定义一个:

      static std::map<test_t*, int> is;
      

      ...每个元素的第一部分是一个this 指针。

      但是,为什么?

      创建一个成员变量。

      【讨论】:

      • 如果将实例分配在与先前删除的实例相同的地址,则映射想法将失败。它也会泄漏内存。
      • @interjay 这当然不是一个好主意!你可能是对的,我本可以更多地强调这一点,但有理由。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-29
      • 1970-01-01
      • 2012-08-04
      • 2017-12-08
      • 1970-01-01
      相关资源
      最近更新 更多