无论如何从内部范围的外部作用域初始化对象?

时间:2010-10-15 09:06:36

标签: c++ scope initialization

例如:

int main()
{
    {
        // I want this array to be part of the inner scope
        string s[] = {"Ben","Joe","Bob","Matt"};

        // And I want to use it to initialize this vector, but I want this
        // vector to be visible in the outer scope
        vector<string> names(s,s+4);
    }
}

有没有办法做到这一点?

6 个答案:

答案 0 :(得分:4)

如果希望向量在外部作用域中可见,则必须在外部作用域中声明它。这意味着你还必须在那里初始化它。 在没有初始化的情况下声明它的唯一方法是使用指针:

int main()
{
  vector<string> * names = 0;

  {
    string s[] = {"Ben", "Joe", "Bob", "Matt"};
    names = new vector<string>(s, s+4);
  }

  // ...
  delete names;
}

答案 1 :(得分:1)

int main()
{
    vector<string> names;
    {       
        string s[] = {"Ben","Joe","Bob","Matt"};
        names.assign(s,s+4);
    }
}

答案 2 :(得分:0)

ldx提到指针给了我一个想法。我之前从未使用过shared_ptr,但我认为它可能是解决方案,所以我查了一下,然后我想出了这个解决方案:

编辑:已更改为auto_ptr

int main()
{
    auto_ptr<vector<string> > vsptr;

    {
        string s[] = {"Ben", "Joe", "Bob", "Matt"};
        int cnt = sizeof(s)/sizeof(string);

        vsptr = auto_ptr<vector<string> >(new vector<string>(s,s+cnt));
    }

    vector<string> &names = *vsptr;
}

我用一个宣布它的构造函数,赋值和析构函数的类来测试它,并且只有一个默认构造和一个破坏。当然,如果你的编译器还没有实现tr1,那么这需要提升,但是值得一试的编译器不是吗?

答案 3 :(得分:0)

虽然没有严格初始化向量,但如果您希望对象是自动而不是动态分配,则可以将其与临时交换:

{
    vector<string> names;

    {
        string s[] = {"Ben","Joe","Bob","Matt"};

        vector<string> init (s,s+4)

        swap ( names, init );
    }
}

虽然你仍然得到主要的副本(复制的char *文字来构造数组中的std :: strings,然后将数组中的std :: strings复制到向量中)交换避免了副本从init到名称的字符串。

答案 4 :(得分:0)

没有办法完全按照你的要求去做。正如其他人所指出的那样,有几种可能性:

  1. 在内部范围之前声明向量,并在此期间填充它。这有一个缺点,即向量悬空一点,这不是好的风格,并且通过稍后初始化而不是构造函数可能有一个小小的,很小的开销,但这些都不应该重要,因为向量必须在任何一点建造。

    //在此处插入代码示例,从其他答案(?)

  2. 中删除
  3. 在内部作用域之前声明一个scoped_ptr(或const auto_ptr,或普通指针),并在内部作用域中 new 一个向量,使用构造函数初始化它,并将其赋值给指针。这几乎没有任何缺点。你必须习惯使用 - &gt;而不是 。但无论如何,大多数C ++程序必须在任何地方都这样做。在内部作用域之前意外使用未分配指针的风险很小,但它应该立即产生异常,因此您应该注意。

    //在此处插入代码示例,从其他答案(?)

  4. 中删除
  5. 在函数中包含整个内部范围或字符串数​​组。这看起来像复杂性,但老实说,我很少很遗憾在一个明确命名的函数中进行常量初始化。该函数可以返回数组,也可以直接返回向量(取决于您是否真的需要内部作用域中的数据,或者只是想避免它污染外部作用域)。根据您的方式,它可能看起来像:

    vector MyFriends(){   const string s [] = {“Ben”,“Joe”,“Bob”,“Matt”};   返回向量(s,s +(sizeof(s)/ sizeof(s [0]))); // TODO:改进计算     //注意使用返回值优化     //可能没关系,但是如果你关心,编译器可能会省略其中一个或两个     //隐含的临时矢量对象 }

    int main(){   {     // 做东西     //如果MyFriends依赖于东西,如果可能的话,可能会将东西移入该函数中     //如果东西只需要访问MyFriends返回值,请在此处再次调用它   }   矢量vec(MYFriends());

    //更多东西 }

  6. 如果您只想在示例3中初始化向量,我认为C ++ 0x支持特定的语法来执行此操作(??)

    //提供示例

答案 5 :(得分:0)

自从我提出这个问题以来,我发现了一个更好的方法来使用lambdas:

int main()
{
    std::vector<std::string> v = []() -> std::vector<std::string> {
        std::string s[] = {"Ben","Joe","Bob","Matt"};
        int cnt = sizeof(s)/sizeof(s[0]);
        return std::vector<string>(s,s+cnt);
    }();
}