2014-02-15 2 views
5

는 I는 펑이함수에서 정의 된 펑터를 다른 함수로 전달할 수없는 이유는 무엇입니까?

using namespace std; 
int main(int argc, char* argv[]) 
{ 
    struct MYINC { 
     int operator()(int a) { return a+1; } 
    } myinc; 
    vector<int> vec; 
    for (int i = 0; i < 10; i++) vec.push_back(myinc(i)); 
    return 0; 
} 

같은 함수 내의 함수를 정의 시뮬레이션하는 데 사용하지만 이러한 표준으로서, 외부 함수에 전달 된 경우 : 다음의 예와 같이 변환 될 수 발견 I

using namespace std; 
int main(int argc, char* argv[]) 
{ 
    struct MYINC{ 
     int operator()(int a) { return a+1; } 
    } myinc; 
    vector<int> vec; 
    for (int i = 0; i < 10; i++) vec.push_back(i); 
    transform(vec.begin(), vec.end(), vec.begin(), myinc); 
    return 0; 
} 

error: no matching function for call to ‘transform(std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator, main(int, char**)::MYINC&)’ 그래서 나는 주요 함수 외부 정의를 넣어 모두가 지금은 OK입니다 말하는 컴파일 오류가 발생했습니다 맞는지. C++ 템플릿을 인스턴스화하는 데 사용할 수있는 유형에 03에서 잘 알려진 꽤 성가신 제한 (WAS)가 나에게 완전히 명확하지 않은 이유로

using namespace std; 
struct MYINC{ 
    int operator()(int a) { return a+1; } 
} myinc; 
int main(int argc, char* argv[]) 
{ 
    vector<int> vec; 
    for (int i = 0; i < 10; i++) vec.push_back(i); 
    transform(vec.begin(), vec.end(), vec.begin(), myinc); 
    return 0; 
} 
+0

[중복 된 답변] (http://stackoverflow.com/questions/9772446/c-local-class-as-functor)을 발견했습니다. –

답변

6

두 버전 모두 g ++ 4.8.2 (C++ 11 컴파일러)로 정상적으로 컴파일됩니다.

C++ 03 컴파일러는 C++ 03에서 지원되지 않았기 때문에 로컬 형식의 템플릿을 인스턴스화하는 데 방해가됩니다.

실제로 문제의 근원이되는 한 가지 해결책은 최신 컴파일러 버전이나 다른 컴파일러를 사용하는 것입니다.

또 다른 해결책은 C++ 03에서도 로컬 클래스의 구성원 함수 인 (C++ 11의 멤버 함수)을 사용하여 "실제"함수를 로컬에서 정의 할 수 있다는 것입니다. 람다 표현식을 사용하여).

그러나, 이러한 문제를 다루는을 제외하고는 펑은 "진짜"기능을 통해 일반적인 성능 이점이있다, 즉 그 대신 함수 포인터의 클래스의 객체와 함께 관련 operator()inline로 컴파일러는 함수 구현을 알고 있기 때문에 훨씬 더 최적화 할 수 있습니다.

+0

위대하고 유용한 답변! C++ 11 표준에서이 새로운 기능이 지원되는 것으로 정의 된 곳을 아는 것은 좋을 것입니다. –

+2

@ DanNissenbaum; C++ 98에서는 (C++ 03에서는 수정이 없었음에도 불구하고) §14.3.1/2에 명시되어있었습니다. "지역 유형, 연결이없는 유형, 이름이없는 유형 또는 이러한 유형 중 하나에서 복합 된 유형은 템플리트 유형 매개 변수에 대한 템플리트 - 인수로 사용됩니다. " 이 요구 사항은 C++ 11에서 제거되었습니다. 따라서 C++ 11에서 "지원되는 것으로 정의 된"이 아닌 능력은 암시 적으로 제한 요구 사항이 없으므로 명시 적으로 지정하기가 어렵습니다. :-) –

1

.

로컬로 정의 된 클래스는 템플릿의 매개 변수로 사용할 수 없습니다.

<algorithm> 라이브러리의 적절한 사용을 어렵게 만들었습니다. 코드의 컨텍스트를 로컬로 유지할 수 없기 때문에 대신 모든 펑터, 비교 자 등을 네임 스페이스 수준으로 배치해야합니다. 그 (것)들을위한 재미 있은 이름 및 사용의 점에서 멀리두기.

+0

Re "로컬로 정의 된 클래스는 템플릿에서 매개 변수로 사용할 수 없습니다."즉 C++ 03에서 사용되었지만 더 이상 현재 표준 인 C++ 11에서는 사용되지 않습니다. 다시 말해, "그냥"때문에, ut는 로컬 타입이 연결되어 있지 않다는 사실에 연결되었습니다. 하지만 C++ 03에서 왜 st * stopper 였는지에 대한 자세한 내용은 명확하지 않습니다. –

+0

@ Cheersandhth.-Alf : 수정 됨. C++ 11이 그 말도 안되는 한계를 제거했다는 것을 알고 있습니다. – 6502

관련 문제