使用std :: function初始化匿名类成员变量

时间:2016-06-16 16:11:07

标签: c++ c++11 default-value std-function

我想知道是否有解决方法就是这样的情况:

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 - 这很糟糕,因为这需要源文件,这需要创建这样的文件,这需要一些efford和破坏我美丽的标题类层次结构! (我的意思是,我可能很懒,并在标题中定义此变量,但随后出现多重定义问题)。我知道这可能是一个糟糕的设计(我只是测试一下),但你有没有想法如何解决问题而不涉及源文件?

3 个答案:

答案 0 :(得分:1)

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

但是,为什么要使用std :: function&lt;&gt;?为什么不直接使用函数?

findLimit(new_starting_limit);

虽然,我通常不会使用decltype(B);我会给这个班级一个名字。

答案 1 :(得分:0)

我觉得我在某种程度上颠覆了你的意图,但是如果你在构造函数中初始化变量,你就可以使事情有效。

#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;
}

答案 2 :(得分:0)

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;
}