문제

나와 같은 대부분의 C ++ 프로그래머는 어느 시점에서 다음과 같은 실수를 저질렀습니다.

class C { /*...*/ };

int main() {
  C c();     // declares a function c taking no arguments returning a C,
             // not, as intended by most, an object c of type C initialized
             // using the default constructor.
  c.foo();   // compiler complains here.

  //...
}

이제 오류가 꽤 분명하지만, 당신이 그것을 알게되면 나는 당신이 할 수 있다는 것을 제외하고 이런 종류의 로컬 기능 선언에 현명한 용도가 있는지 궁금합니다. 정의하다 동일한 블록의 그러한 국소 기능; 당신은 다른 곳에서 그것을 정의해야합니다.

자바 스타일 로컬 클래스는 자주 사용하는 경향이있는 매우 좋은 기능, 특히 익명의 종류라고 생각합니다. 현지 C ++ 클래스 (인라인 정의 멤버 기능을 가질 수 있음)조차도 약간의 사용이 있습니다. 그러나 정의가없는이 로컬 기능 선언은 나에게 매우 어색해 보입니다. 그것은 단지 C- 레게 유산입니까 아니면 내가 알지 못하는 더 깊은 사용 사례가 있습니까?

편집하다 불신자를 위해 : C c() ~이다 ~ 아니다 함수 포인터 선언.

이 프로그램

int main()
{
  void g();
  cout << "Hello ";
  g();
  return 0;
}

void g()
{
  cout << "world." << endl;
}

출력 Hello world. 이 프로그램

void fun()
{
  cout << "world." << endl;
}

int main()
{
  void g();
  g = fun;
  cout << "Hello ";
  g();
  return 0;
}

컴파일하지 않습니다. GCC는 다음과 같이 불평합니다.

error: cannot convert 'void ()()' to 'void ()()' in assignment

comeau :

error: expression must be a modifiable lvalue
도움이 되었습니까?

해결책

나는 다른 기능에 인수로 전달하고 싶을 때 C에서 로컬 기능 선언을 원했습니다. 나는 항상 다른 언어로 이것을합니다. 그 이유는 데이터 구조의 구현을 캡슐화하는 것입니다.

예를 들어 트리 나 그래프와 같은 데이터 구조를 정의하고 내부 구현의 세부 사항을 노출시키고 싶지 않습니다. 예를 들어 변경하거나 변경하고 싶을 수도 있습니다. 그래서 나는 액세서와 뮤지토가 요소에 대한 기능과 요소를 반복하는 횡단 기능을 노출시킵니다. 트래버스 함수는 요소에서 작동하는 함수의 인수를 가지고 있습니다. Traversal 함수의 작업은 각 요소에서 인수 함수를 실행하고 결과를 어떤 방식 으로든 집계하는 것입니다. 이제 트래버스 함수를 호출 할 때 인수 함수는 일반적으로 로컬 상태에 의존하는 일부 특수 작업이므로 로컬 기능으로 정의되어야합니다. 로컬 상태를 포함하는 변수를 외부로, 외부로, 또는 그들을 붙잡기 위해 구체적으로 만들어진 내부 클래스로 기능을 밀어야하는 것은 엉덩이가 못 생겼습니다. 그러나 이것은 C ++가 아닌 C와 Java와 관련된 문제입니다.

다른 팁

내가 생각할 수있는 유일한 용도는 기능 선언의 범위를 줄이는 것입니다.

int main()
{
    void doSomething();
    doSomething();
    return 0;
}

void otherFunc()
{
    doSomething();  // ERROR, doSomething() not in scope
}

void doSomething()
{
    ...
}

물론 이에 대한 더 나은 솔루션이 있습니다. 함수를 숨겨야하는 경우, 기능을 별도의 모듈로 이동시켜 코드를 구조 조정하여 숨길 기능을 호출 해야하는 함수가 모두 동일한 모듈에 있도록해야합니다. 그런 다음 정적 (C way)을 선언하거나 익명 네임 스페이스 (C ++ 웨이) 안에 넣어 함수 모듈로 만들 수 있습니다.

선언 선언 프로토 타입입니다. 아마도 정의 순서와 달리 서로를 부르는 로컬 기능이나 지역 기능이 많으면 필요할 수 있습니다.

내가 볼 수있는 유일한 제정신 사용은 컴파일 장치의 한 기능 만 다른 컴파일 장치에 정의 된 함수에 대해 알 수 있도록하는 것입니다. 나는 그것이 다소 합리적인 용도라고 생각하지만, 그것이 내가 생각할 수있는 유일한 사람이며, 그것이 과잉이라고 생각합니다.

세 번째 스 니펫에서 말한 것처럼 이 답변, 스코프 섀도 잉에 도움이 될 수 있습니다.

#include <stdio.h>

void c(); // Prototype of a function named ``c''

int main() {

    c(); // call the function

    { // additional scoppe needed for C, not for C++
        int c = 0; // shadow the c function with a c integer variable
        c++;
        {
            void c(); // hide the c integer variable back with the c function
            c();
        }
        ++c;
    } //!

    return 0;
}

void c() {
    printf("Called\n");
}

나는이 용도가 자주 유용 할 가능성이 없으며 잘 설계된 프로그램에서는 발생하지 않을 가능성이 있다고 생각하지 않습니다.

나는 이것이 여전히 그 기능의 가장 큰 이유라고 생각하며, 변수의 경우 최근에 함수를 정의하는 것은 옳지 않은 소리가 아닙니다.

나는 때때로 우리가 처음으로 사용하기 직전에 (그리고 더 일찍가 아니라), 즉, 가독성을 향상시키기 위해 변수를 선언하도록 권장되는 것과 같은 이유로 때때로 그렇게합니다. (예, 변수의 경우 첫 번째 사용이라고 생각하기 전에 변수가 사용되는지 여부를 확인해야하기 때문에 더 중요하다는 것을 알고 있습니다). 프로토 타입 (특히 단순한 것보다 더 관여하는 경우 c()) 함수 호출에 가깝게 가독성이 향상됩니다. 특별한 경우 C c() 인간에게 오해의 소지가 있지만 불행한 일이지만, 지역적으로 기능을 선언한다는 일반적인 아이디어에는 장점이 있습니다.

물론 이것은 이미 범위에있는 함수 이름에도 적용됩니다. 모든 기능을 사용하기 전에 모든 기능을 다시 고정하지 않겠습니까? 그것에 대한 나의 대답 : 적당히 모든 일을하십시오. 너무 많은 혼란은 가독성을 방해합니다 (기능의 서명이 변경 될 경우 유지 관리 가능성 ---). 따라서 나는 그것으로부터 규칙을 제시하지는 않지만 때로는 기능을 로컬로 선언하는 것이 유용합니다.

매개 변수를 가져 오지 않는 함수 선언과 기본 소멸 자로 클래스를 인스턴스화하는 것과 다르려면 괄호를 건너 뜁니다.

class C
{
  public:
    void foo() {}
};


int main()
{
    // declare function d, taking no arguments, returning fresh C
    C d();

    // instantiate class (leave parenthesis out)
    C c;
    c.foo();

    // call declared function
    C goo = d();

    return 0;
}

C d()
{
    C c;
    // ..
    return c;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top