使用STD ::函数的匿名类成员变量的初始化

Initialization of anonymous class member variable with std::function

本文关键字:成员 初始化 变量 STD 函数 使用      更新时间:2023-10-16

我想知道是否有解决方法:

class A
{
    class
    {
    public:
        void setValue(int val) {i=val;}
    private:
        int i;
    } B = initB(10);
    std::function<decltype(B)(int)> initB = [this](int value)
                                            {decltype(B) temp;
                                             temp.setValue(value);
                                             return temp;};
}

//...
    A a; //crash
//...

我想这是由初始化顺序引起的。可变B是通过调用未定性的std::function实例来发起的,因此崩溃。通过我的逻辑,解决方法是先初始化std::function,然后初始化成员B。但是,此类代码无效:

class A
    {
        //error: 'B' was not declared in this scope
        std::function<decltype(B)(int)> initB = [this](int value)
                                                {decltype(B) temp;
                                                 temp.setValue(value);
                                                 return temp;};
        class
        {
        public:
            void setValue(int val) {i=val;}
        private:
            int i;
        } B = initB(10);
    }

我试图制作std::function static,并且此类代码有效,但需要non-constexpr/const成员,因为std :: function具有 non-trivial destructor-不好,因为这需要源文件,这需要创建此类文件,这需要一些文件效果和破坏我美丽的仅标题级别的层次结构!(我的意思是,我可能会很懒惰,并在标题中定义了此变量,但随后发生了多个定义问题)。我知道这可能是一个糟糕的设计(我只是在测试内容),但是您是否有任何想法在不涉及源文件的情况下解决问题?

尽管您的示例是人为的,但有时我需要(或更方便)以类似的方式初始化复杂对象。

但是,为什么要使用std :: function&lt;>?为什么不使用功能?

class A
{
    class
    {
    public:
        void setValue(int val) { i = val; }
    private:
        int i;
    } B = initB(10);
    static decltype(B) initB(int value)
    {
        decltype(B) temp;
        temp.setValue(value);
        return temp; 
    }
};

,尽管我通常不会使用dectType(b);我只会给班级一个名字。

我觉得自己在某种程度上颠覆了您的意图,但是如果您初始化构造函数中的变量,则可以使事物正常工作。

#include <functional>
class A
{
  class
  {
   public:
    void setValue(int val) {i=val;}
   private:
    int i;
  } B;
  std::function<decltype(B)(int)> initB;
 public:
  A() {
    initB = [this](int value)
            {decltype(B) temp;
             temp.setValue(value);
             return temp;};
    B = initB(10);
  }
};
int main() {
  A a;
}

a :: initb是一个值。它不是在您调用它的点上初始化的,因为在指定会员字段的顺序下完成了初始化(松散说话)。您可以通过执行以下操作来验证这一点:

#include <iostream>
#include <functional>
using namespace std;
template<typename T, typename U>
T set(T& tgt, const U& src)
{
    new(&tgt) T(src);
    return tgt;
}
class A
{
    class
    {
    public:
        void setValue(int val) {i=val;}
    private:
        int i;
    } B = set(initB, [this](int value)
                        {decltype(B) temp;
                         temp.setValue(value);
                         return temp;})(10);
    std::function<decltype(B)(int)> initB;
};

int main() {
    A a;
}