2011-08-18 3 views
8

죄송합니다. 이전에이 질문을 받았지만 찾을 수 없었습니다.함수 포인터 대신 값 (?)을 전달합니까?

그래서 저는 템플릿과 새로운 C++ 11 기능 (주로 람다, 항상 다른 언어로 좋아하는 것)에 대해 직접 교육하려고합니다.

는하지만 내 테스트에서 나는이 일을 몰랐다 뭔가오고, 나는 그것이하지만 캔트 그림 그것을 밖으로 ..

다음 코드 작동 방식을 이해하기 위해 노력하고있어 :

template <class Func> 
void Test(Func callback) { 
    callback(3); 
} 

void Callback(int i) { 
    std::cout << i << std::endl; 
} 

int main(int argc, char** argv) { 
    Test(&Callback); // this I was expecting to work, compiler will see its a pointer to a function 
    Test(Callback); // this also works, but how?! 
    return 0; 
} 

템플릿이 어떻게 작동 하는지를 이해한다면 기본적으로 컴파일러는 무엇을 빌드해야하는지 알기 때문에 첫 번째 호출은 Test(&Callback);입니다. 컴파일러가 템플릿이 함수 주소를 받고 인자가 있어야한다고 생각하기 때문에 작동 할 것으로 예상됩니다. 포인터.

하지만 두 번째 호출은 무엇입니까? 그것을 가정하는 템플릿은 무엇입니까? functio의 복사본 (심지어 의미가있는 경우)?

답변

14

함수는 암시 적으로 자체에 대한 포인터로 변환 가능합니다. 이 전환은 거의 모든 곳에서 발생합니다. Test(Callback)은 정확히 Test(&Callback)과 같습니다. 다른 점이 없다. 두 경우 모두 Funcvoid(*)(int)으로 추정됩니다.

함수 포인터가 이상합니다. 그들에 대한 자세한 내용은 "Why do all these crazy function pointer definitions all work?"

+0

답을 고맙습니다. 그래서 만약 내가 템플릿을 사용하지 않으면 Test : void Test (void (* callback) (int)) {...} 두 호출 모두 잘 동작 할 것이다. 알고있는 것이 좋다. 내가 연결된 스레드를 읽었는지 확인하십시오. – sap

3

에서 찾을 수 있습니다. C++에서 함수는 "값으로 함수"를 의미하는 일등급 객체가 아닙니다. 그래서 함수 이름은 항상 암시 적으로 포인터로 변환 될 수 있습니다.

+0

아마도 "가치에 의한 기능"이 의미있는 언어보다 더 주목할 가치가 있습니다. – hamstergene

2

함수는 함수 포인터로 암시 적으로 변환 가능합니다. 사실 함수 값이나 참조를 얻을 수있는 방법이 없다면. 이상하게도 함수 값 유형을 만들 수 있지만 아무 것도 할당 할 수 없습니다.

Here is code snippit 이것은 람다와 다양한 콜백이 템플릿과 어떻게 반응하는지 보여줍니다.

+0

정말 도움이되는 코드에 감사드립니다. – sap

+0

잘못되었습니다. 함수 참조가 좋습니다. 만약'Test'가'void Test (Func & callback)'로 선언 되었다면,'Func'는'void (int)'로 추론 될 것이고'Callback'은 포인터로 변환되지 않고 참조로 전달 될 것입니다. 테스트 '. –

+0

와우! 나는 그것들이 매우 유사하기 때문에 참조가 포인터뿐만 아니라 지원되어야한다는 것이 합리적이라고 생각한다. 함수 값을 선언하고 무언가를 할당 할 수 있습니까? –

0

C++ 11 (및 boost와 tr1)에서는 펑터, 람다 및 함수를 저장하기위한 템플릿 유형으로 std :: function을 사용합니다. 따라서 std :: function 유형의 변수에 함수 값을 유지하는 개념을 확실히 가질 수 있습니다. 그 변수는 "비어있을"수도 있습니다. 즉 함수 (참조)가 저장되어 있지 않음을 의미합니다. 그런 다음 호출 할 수 없습니다.

원래의 질문은 C와는 달리 C++에서 함수 참조를 허용한다는 점입니다. 또한 C와의 호환성을 위해 함수 이름을 함수 포인터로 축약 할 수 있습니다. 하지만 overloading 때문에 C보다 C++에서 "재미있는"것이 있습니다.