2014-11-11 2 views
2

개방형 문자열 배열의 내용을 익명 함수로 전달할 때 열려있는 배열을 기대하는 다른 함수로 전달하는 데 낭비되는 최소한의 방법은 무엇입니까?오픈 어레이를 익명 함수로 전달

오픈 어레이는 Delphi XE2의 익명 함수에서 캡처 할 수 없습니다.

procedure TMyClass.DoSomething(const aStrings: array of string); 
begin 
    EnumItems(
    function (aItem: string) : Boolean 
    begin 
     Result := IndexText(aItem, aStrings) >= 0; 
    end); 
end; 

컴파일러는 불평 : "기호 'aStrings'을 캡처 할 수 없습니다"

는 문제를 보여줍니다.

명백한 해결책은 동적 배열에 aString 복사본을 만들고 캡처하는 것입니다. 하지만 나는 복사본을 만들고 싶지 않습니다. (내 특정 문제는 문자열 배열을 포함하고 복사본을 만드는 것은 참조 횟수로 인해 문자열 데이터 자체가 아닌 포인터 만 복사하는 것이므로 임의로 큰 비평가 배열에 대한 문제를 해결하는 방법을 배우는 것도 도움이 될 것입니다

그래서 나는 PString aStrings의 첫 번째 문자열 포인터와 길이의 Integer 값을 캡처하려고했습니다. 그러나 나는 이것을 InsertText에게 넘겨 줄 방법을 찾지 못했습니다.

다른 하나의 제약 : DoSomething([a, b, c])으로 전화를 걸 수 있습니다.

IndexText의 내 자신의 버전을 작성하지 않고, 그리고 끔찍한 못생긴하지 않고 배열의 복사본을 만들지 않고이를 수행 할 수있는 방법이 있습니까? 그렇다면 어떻게?

나는이 질문을 위해서 IndexText을 사용했지만 개방형 배열 대신 포인터와 길이 매개 변수를 받아들이도록 쉽게 작성할 수없는 함수에 대한 해결책을 찾는 것이 좋습니다.

이 질문에 대한 대답은 다음과 같습니다. 아니, 적어도 복사하지 않고 (다시 작성하거나 IndexText을 다시 작성하지 않아도) 그렇게 할 수는 없지만 그렇게하는 것이 가장 기본적인 이유를 알고 싶습니다.

답변

3

배열을 복사하지 않으려면 대신 DoSomething의 서명을 TArray<string>으로 변경해야합니다. 물론 요소를 직접 전달하는 경우 호출자 측을 변경해야합니다 (동일한 방법으로 동적 배열을 전달할 수있는 XE7 이후에만) - DoSomething([a, b, c])과 같은 의미입니다.

내 조언은 일부 내부 포인터와 물건들, 특히 개방형 배열을 둘러 먹는 것이 아닙니다.

+0

예, 전화 한건'해봐요 ([A, B, C]) ':-( –

+2

@IanGoldby은 : 다음 동적'TArrayNoInit이 '를 생성하고 전달 XE7에서 함께 수행 될 수있다. : myArray : = TArray .Create (a, b, c);'를 사용하여 수행 할 수 있지만 매우 효과적이지는 않습니다 .하지만 OTOH, 오픈 배열 매개 변수 생성자 중 하나는 매우 잘 수행되지 않습니다. 복사를 피하기 위해 매개 변수가'const'인지 확인하십시오. –

2

복사본을 만들지 않고이를 수행 할 방법이 없습니다. 공개 배열은 발견 한대로 캡처 할 수 없으며 캡처하지 않고 익명 메소드로 정보를 가져올 수 없습니다. 일반적으로 변수의 수명을 연장해야하기 때문에 캡처해야합니다.

오픈 어레이에서이 작업을 수행 할 수 없으므로 복사본을 만들 수 없습니다. 대신 다음을 수행 할 수 있습니다.

  1. 개방 배열에서 동적 배열 TArray<string>으로 전환하십시오.
  2. 어레이 사본을 만드십시오. 문자열 데이터를 복사하지 않고 문자열에 대한 참조 배열 만 복사하면됩니다.
+0

배열의 첫 번째 요소에 대한 포인터를 캡처 할 수는 있지만 그럼 당신은 더 이상'IndexText'에 전달할 배열을 열지 않았을 것입니다. 두번째 부분은 해결책이있을 것이라고 생각했습니다. 여러분이 말하지 않는 것처럼 들립니다. –

+0

anon 메서드는 b 오픈 어레이의 범위를 넘어서. 그런 다음 포인터가 유효하지 않습니다. 그것이 내가하려는 것입니다. –

+0

OK, 평생 동안의 문제 (그리고 컴파일러가 열린 배열 매개 변수를 캡처하지 않는 이유)에 대해 알고 있습니다. 나는 anon 메서드 *가 배열보다 오래 남아 있지 않을 것이고 포인터와 길이 매개 변수가 'IndexText'에 대한 열린 배열처럼 보이는 구문이 있는지 궁금해합니다. 장난'). –