연산자 [] [] 오버로드 허용하려면 다음과 같이하십시오. function[3][3](2

[]연산자를 두 번 오버로드 할 수 있습니까? 허용하려면 다음과 같이하십시오. function[3][3](2 차원 배열에서와 같이).

가능하다면 몇 가지 예제 코드를보고 싶습니다.



답변

결과를 얻기 operator[]위해 operator[]다시 사용할 수있는 객체를 반환하도록 오버로드 할 수 있습니다.

class ArrayOfArrays {
public:
    ArrayOfArrays() {
        _arrayofarrays = new int*[10];
        for(int i = 0; i < 10; ++i)
            _arrayofarrays[i] = new int[10];
    }

    class Proxy {
    public:
        Proxy(int* _array) : _array(_array) { }

        int operator[](int index) {
            return _array[index];
        }
    private:
        int* _array;
    };

    Proxy operator[](int index) {
        return Proxy(_arrayofarrays[index]);
    }

private:
    int** _arrayofarrays;
};

그런 다음 다음과 같이 사용할 수 있습니다.

ArrayOfArrays aoa;
aoa[3][5];

이것은 단순한 예에 불과합니다. 경계 검사 및 항목을 추가하고 싶지만 아이디어를 얻었습니다.


답변

을 지원 하는 객체로 평가 되는 표현식이 x[y][z]필요 합니다 .x[y]dd[z]

이 수단 x[y]가진 객체되어야 operator[]는 “프록시 객체”에 해당 평가하여 을 지원한다 operator[].

이것이 그들을 연결하는 유일한 방법입니다.

또는을 operator()호출 할 수 있도록 오버로드 하여 여러 인수를 가져옵니다 myObject(x,y).


답변

특히 2 차원 배열의 경우 각 행의 첫 번째 요소에 대한 포인터를 반환하는 단일 operator [] 오버로드를 사용할 수 있습니다.

그런 다음 내장 인덱싱 연산자를 사용하여 행 내의 각 요소에 액세스 할 수 있습니다.


답변

첫 번째 [] 호출에서 어떤 종류의 프록시 클래스를 반환하면 가능합니다. 그러나 다른 옵션이 있습니다. 임의의 수의 인수 ( function(3,3))를 허용 할 수있는 operator ()를 오버로드 할 수 있습니다 .


답변

한 가지 접근 방식은 다음을 사용하는 것입니다 std::pair<int,int>.

class Array2D
{
    int** m_p2dArray;
public:
    int operator[](const std::pair<int,int>& Index)
    {
       return m_p2dArray[Index.first][Index.second];
    }
};

int main()
{
    Array2D theArray;
    pair<int, int> theIndex(2,3);
    int nValue;
    nValue = theArray[theIndex];
}

물론, 당신은 할 수있다typedefpair<int,int>


답변

다음과 같은 프록시 객체를 사용할 수 있습니다.

#include <iostream>

struct Object
{
    struct Proxy
    {
        Object *mObj;
        int mI;

        Proxy(Object *obj, int i)
        : mObj(obj), mI(i)
        {
        }

        int operator[](int j)
        {
            return mI * j;
        }
    };

    Proxy operator[](int i)
    {
        return Proxy(this, i);
    }
};

int main()
{
    Object o;
    std::cout << o[2][3] << std::endl;
}

답변

그것은 ‘당신은 내가 무엇을 알릴 수 있다면 좋을 것이다 function, function[x]그리고function[x][y] 있습니다. 그러나 어쨌든 어딘가에 선언 된 객체로 간주하겠습니다.

SomeClass function;

(연산자 과부하라고 말했기 때문에 배열에 관심이 없을 것 같습니다. SomeClass function[16][32];)

그래서 function유형의 인스턴스입니다 SomeClass. 그런 다음 SomeClass반환 유형의 operator[]오버로드 에 대한 선언을 찾습니다.

ReturnType operator[](ParamType);

그런 다음 function[x]유형이 ReturnType있습니다. 다시 찾아 ReturnType에 대한 operator[]과부하. 이러한 방법이 있으면 다음 식을 사용할 수 있습니다.function[x][y] .

참고 달리 function(x, y), function[x][y]이 별도의 전화입니다. 따라서 컨텍스트에서 잠금을 사용하지 않는 한 컴파일러 또는 런타임이 원 자성을 보장하기가 어렵습니다. 유사한 예는 libc printf가 원자 적이 라고 말하지만 operator<<출력 스트림 의 오버로드 에 대한 연속 호출 은 그렇지 않습니다. 다음과 같은 진술

std::cout << "hello" << std::endl;

다중 스레드 응용 프로그램에서 문제가있을 수 있지만

printf("%s%s", "hello", "\n");

괜찮습니다.