简体   繁体   English

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

[英]Is there anyway to initialize an object from an outer scope in an inner scope?

For example: 例如:

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

Is there any way to do that? 有什么办法吗?

If you want the vector to be visible in the outer scope, you must declare it in the outer scope. 如果希望向量在外部范围中可见,则必须在外部范围中声明它。 Which means that you also have to initialize it there. 这意味着您还必须在那里初始化它。 The only way to declare it without initializing is by using a pointer: 无需初始化即可声明它的唯一方法是使用指针:

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

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

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

ldx's mentioning of pointers gave me an idea. ldx提到指针给了我一个主意。 I've never used shared_ptr before, but I thought it might be the solution, so I looked them up, and I came up with this solution: 我以前从未使用过shared_ptr,但我认为这可能是解决方案,因此我进行了查找,然后提出了以下解决方案:

Edit: changed to auto_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;
}

I tested it with a class that announces it's constructors, assignments and destructors, and there's only one default construction and one destruction. 我用一个宣布它的构造函数,赋值和析构函数的类对其进行了测试,并且只有一个默认构造和一个销毁。 Of course, this requires boost if your compiler doesn't implement tr1 yet, but what compiler worth a damn doesn't? 当然,如果您的编译器尚未实现tr1,则这需要增强,但是值得该死的编译器没有实现吗?

Although not strictly initialising the vector, if you want your object to be auto rather than dynamically allocated you can swap it with a temporary: 尽管没有严格初始化向量,但是如果您希望对象是自动的而不是动态分配的,则可以将其与临时对象交换:

{
    vector<string> names;

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

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

        swap ( names, init );
    }
}

Though you still get the major copies going on ( the char* literals copied to construct the std::strings in the array, then the std::strings in the array copied to the vector ) the swap avoids the copy of the strings from init to names. 尽管您仍在进行主要复制(将char *文字复制以构造数组中的std :: strings,然后将数组中的std :: strings复制到vector),但是交换可以避免从init复制字符串到名字。

There is no way to do exactly what you asked for. 无法完全按照您的要求进行操作。 There are several possibilities, as other people have pointed out: 正如其他人指出的那样,有几种可能性:

  1. Declare the vector before the inner scope, and populate it during. 在内部范围之前声明矢量,并在内部范围内填充它。 This has the downside that the vector is hanging around empty for a bit, which is not good style, and there may be a teeny, teeny overhead by initialising it later rather than the constructor, but neither of these should matter much, since the vector has to be constructed at some point either way. 缺点是向量在空的位置上徘徊了一点,这不是一个好的样式,通过稍后对其进行初始化而不是构造函数,可能会产生很小的开销,但是这两个都不重要,因为向量必须以某种方式在任何时候构建。

    // insert code sample here, cribbed from other answer (?) //在此处插入代码示例,从其他答案中复制该代码(?)

  2. Declare a scoped_ptr (or const auto_ptr, or normal pointer) before the inner scope, and new a vector in the inner scope, initialising it using the constructor, and assign it to the pointer. 在内部作用域之前声明一个scoped_ptr(或const auto_ptr或普通指针),并在内部作用域中新建一个向量,使用构造函数对其进行初始化,然后将其分配给指针。 This has almost no downside. 这几乎没有缺点。 You have to get used to using -> rather than . 您必须习惯使用->而不是。 but most C++ programs have to do that everywhere anyway. 但是大多数C ++程序无论如何都必须这样做。 There's a small risk you will accidentally use the unallocated pointer before the inner scope, but it should immediately produce an exception, so you should notice. 您可能会不小心在内部作用域之前使用未分配的指针,但是它应该立即产生异常,因此应该注意。

    // insert code sample here, cribbed from other answer (?) //在此处插入代码示例,从其他答案中复制该代码(?)

  3. Wrap up either the whole inner scope, or just the string array, in a function. 在函数中包装整个内部范围或仅字符串数组。 This looks like complexity, but honestly, I have very very rarely regretted having the constant initialization in a clearly named function. 这看起来很复杂,但是老实说,我很少后悔在一个明确命名的函数中进行常量初始化。 The function can either return the array, or return a vector directly (depending whether you really need that data in the inner scope, or just want to avoid it contaminating the outer scope). 该函数可以返回数组,也可以直接返回向量(取决于您是否确实需要内部范围中的数据,或者只是想避免污染外部范围)。 Depending which way you go, it might look something like: 根据您走的路,它可能看起来像:

    vector MyFriends() { const string s[] = {"Ben","Joe","Bob","Matt"}; 向量MyFriends(){const string s [] = {“ Ben”,“ Joe”,“ Bob”,“ Matt”}; return vector(s, s + (sizeof(s)/sizeof(s[0])) ); 返回向量(s,s +(sizeof(s)/ sizeof(s [0]))); // TODO: improve the calc // Note use of return value optimisation // Probably doesn't matter, but if you care, compilers may omit one or both // of the implied temporary vector objects. // TODO:改进calc //注意返回值优化的使用//可能无关紧要,但是如果您在意,编译器可能会省略一个或两个隐含的临时矢量对象。 } }

    int main() { { // Do stuff // If MyFriends depends on stuff, possibly move stuff into that func if possible // If stuff just needs access to MyFriends return value, call it again here } vector vec(MYFriends()); int main(){{//做东西//如果MyFriends依赖于东西,可能的话将其移入该函数// //如果东西只需要访问MyFriends返回值,请在此处再次调用} vector vec(MYFriends()) ;

    // More stuff } // 更多东西 }

  4. If you only want to initialise the vector as in example 3, I think C++0x supports a specific syntax to do this (??) 如果只想像示例3中那样初始化向量,我认为C ++ 0x支持一种特定的语法来做到这一点(??)

    // Provide example //提供示例

Since I asked this question, I found a much better way to do this using lambdas: 自从我问了这个问题之后,我发现了一种使用lambda的更好的方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用C ++的std :: move从内部作用域中的对象到外部作用域是否安全? - Is it safe to use C++'s std::move from object in inner scope to outer scope? 在 class function 中初始化外部 scope 变量 - Initialize outer scope variable in class function 处理范围变量的内部函数 - Inner functions dealing with variables from the scope 从内部 scope 访问阴影变量 - Accessing shadowed variables from inner scope 使用来自内部 scope 的变量构造 C++ object ... 可以吗? - Constructing C++ object using variables from an inner scope... can it be done? ADL 名称查找问题,正在使用 std::swap; swap(a,b) related to function overloading or inner scope function hide outer scope function? - ADL name lookup problem, is using std::swap; swap(a,b) related to function overloading or inner scope function hide outer scope function? if语句没有内部范围? - if statement without the inner scope? 嵌套的 function 从外部 scope 继承值而不通过 - Nested function inherit value from outer scope without passing 在重新定义之前从外部 scope 访问变量是否定义良好? - Is it well defined to access a variable from an outer scope before it is redefined? 用外部类初始化内部类有可能吗? - Initialize Inner Class with outer class this possible?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM