Подтвердить что ты не робот

Есть ли способ доступа к локальной переменной во внешней области в С++?

Просто из любопытства: если у меня есть вложенные области, как в этом примере кода на С++

using namespace std;

int v = 1; // global

int main (void)
{
    int v = 2; // local
    {
        int v = 3; // within subscope
        cout << "subscope: " << v << endl;
        // cout << "local: " << v << endl; 
        cout << "global: " << ::v << endl;
    }
    cout << "local: " << v << endl;

    cout << "global: " << ::v << endl;

}

Есть ли способ получить доступ к переменной v со значением 2 из "промежуточной" области (ни глобальной, ни локальной)?

4b9b3361

Ответ 1

Вы можете объявить новую ссылку как псевдоним, например

int main (void)
{
    int v = 2; // local 
    int &vlocal = v;
    {
        int v = 3; // within subscope
        cout << "local: " << vlocal  << endl; 
    }
}

Но я бы вообще избегал этой практики. Я потратил часы на отладку такой конструкции, потому что переменная отображалась в отладчике как измененная из-за области видимости, и я не мог понять, как она изменилась.

Ответ 2

Ответ: Нет. Вы не можете. Переменная в локальной области оттеняет переменную в глобальной области, и язык предоставляет способ доступа к глобальной переменной с использованием квалифицированных имен глобального типа, как и вы. Но С++ как язык не обеспечивает доступа к промежуточной переменной.

Учитывая, что это должно было бы быть разрешено, для этого потребовалось бы много сложной обработки, представьте ситуацию с n количеством областей (вполне может быть бесконечным) и обработкой их.

Вам лучше переименовать свои промежуточные переменные и использовать те, которые будут более логичными и удобными в обслуживании.

Ответ 3

Существует два типа разрешение области видимости в С++ - унарная область действия и область класса. Не существует области действия функции или оператора "любой конкретной родительской области". Это делает невозможным решение вашей проблемы, как и вообще, потому что вы не можете ссылаться на анонимные области. Однако вы можете либо создать псевдоним, переименовать переменные, либо сделать это частью класса, что, конечно же, подразумевает изменение кода. Это самое близкое, что я могу получить без переименования в этом конкретном случае:

#include <iostream>

using namespace std;

int v = 1; // global

class Program
{
    static int v; // local

public:
    static int main ()
    {
        int v = 3; // within subscope
        cout << "subscope: " << v << endl;
        cout << "local: " << Program::v << endl; 
        cout << "global: " << ::v << endl;
    }
};

int Program::v = 2;

int main ()
{
    return Program::main ();
}

Существуют и другие способы, например, убедиться, что переменные не оптимизированы и находятся в стеке, тогда вы можете работать со стеком напрямую, чтобы получить значение переменной, которую вы хотите, но не позволяйте этому идти.

Надеюсь, что это поможет!

Ответ 4

Вы можете подделать это так:

#include <iostream>
using namespace std;
int v = 1;

int main()
{
        int v = 2;
        {
                int &rv = v; // create a reference
                int v = 3; // then shadow it

                cout << "subscope: " << v << endl;
                cout << "local: " << rv << endl;
                cout << "global: " << ::v << endl;
        }
        cout << "local: " << v << endl;

        cout << "global: " << ::v << endl;

        return 0;
}

Интересно, что это компилируется на cygwin g++, но segfaults, если вы попытаетесь запустить его:

#include <iostream>
using namespace std;
int v = 1;

int main()
{
        int v = 2;
        {
                int &v = v;
                cout << "subscope: " << v << endl;
                // cout << "local: " << v << endl; 
                cout << "global: " << ::v << endl;
        }
        cout << "local: " << v << endl;

        cout << "global: " << ::v << endl;

        return 0;
}