문제

다음 코드가 g++ (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-49)에서 컴파일되지 않는 이유를 설명할 수 있는 사람이 있습니까?

struct X {
public:
   enum State { A, B, C };

   X(State s) {}
};

int main()
{
   X(X::A);
}

내가 받는 메시지는 다음과 같습니다.

jjj.cpp:함수 'int main()'에서:
jjj.cpp:10:'X X::A'는 'struct X'의 정적 멤버가 아닙니다.
jjj.cpp:10:'X::X()' 호출에 일치하는 함수가 없습니다.
jjj.cpp:1:후보자는 다음과 같습니다X::X(상수 X&)
jjj.cpp:5:X::X(X::상태)`

이것은 잘못된 코드입니까, 아니면 컴파일러 버그입니까?

Neil+Konrad가 문제를 해결했습니다.아래 Neil의 답변에 대한 의견을 참조하십시오.

도움이 되었습니까?

해결책

X(X::A);

ASA 기능 선언이 보이고 있습니다. 이 코드를 정말로 원한다면 다음을 사용하십시오.

(X)(X::A);

다른 팁

정의에서 변수 이름을 잊어 버렸습니다.

int main()
{
   X my_x(X::A);
}

귀하의 코드는 구문 적으로이를 함수 선언과 구별 할 수 없기 때문에 컴파일러를 혼동합니다 (반환 X 그리고 통과 X::A 논쟁으로). 의심스러운 경우, C ++ 컴파일러는 항상 선언에 찬성하여 명백합니다.

해결책은 주위에 중복 괄호를 도입하는 것입니다 X 컴파일러는 유형 주위에 괄호를 금지하기 때문에 (Constructo 호출 등과 반대로) :

(X(X::A));

무슨 일이 일어나는지 명확하게 하기 위해서입니다.이 예를 보세요

int main() {
    float a = 0;
    {
        int(a); // no-op?
        a = 1;
    }
    cout << a;
}

무엇을 출력할까요?자, 출력됩니다 0.그만큼 int(a) 위의 내용은 두 가지 다른 방식으로 구문 분석될 수 있습니다.

  • int로 캐스팅하고 결과를 폐기합니다.
  • 라는 변수를 선언합니다. a.그러나 식별자 주위의 괄호는 무시하십시오.

함수 스타일의 캐스트가 명령문에 사용되고 선언처럼 보이는 상황이 나타나면 컴파일러는 항상 이를 선언으로 간주합니다.구문상 선언이 될 수 없는 경우(컴파일러는 이를 결정하기 위해 전체 줄을 확인합니다) 표현식으로 간주됩니다.따라서 우리는 내부에 할당하고 있습니다 a 위, 외부를 떠나 a 0에.

자, 당신의 경우가 바로 그것입니다.(우연히)라는 식별자를 선언하려고 합니다. A 라는 클래스 내에서 X:

X (X::A); // parsed as X X::A;

그런 다음 컴파일러는 선언되지 않은 기본 생성자에 대해 불평합니다. 왜냐하면 정적이 가정된 대로 기본 생성자이기 때문입니다.그러나 X에 대한 기본 생성자가 있더라도 물론 여전히 잘못된 것입니다. A X의 정적 멤버이거나 X의 정적 멤버를 블록 범위에서 정의/선언할 수 없습니다.

넌 할 수있어 ~ 아니다 여러 가지 작업을 수행하여 선언처럼 보입니다.첫째, 전체 표현식을 paren하여 더 이상 선언처럼 보이지 않게 할 수 있습니다.아니면 캐스팅되는 유형을 paren으로 지정하세요.이 두 가지 명확성은 다른 답변에서 언급되었습니다.

(X(X::A)); (X)(X::A)

실제로 개체를 선언하려고 하면 비슷하지만 뚜렷한 모호성이 있습니다.이 예를 보세요:

int main() {
    float a = 0;
    int b(int(a)); // object or function?
}

왜냐하면 int(a) 다음과 같은 매개변수의 선언일 수 있습니다. a float 변수를 int로 명시적으로 변환(캐스트)하면 컴파일러는 이것이 선언이라고 다시 결정합니다.그래서 우리는 우연히 다음과 같은 함수를 선언하게 되었습니다. b, 정수 인수를 사용하여 정수를 반환합니다.위의 명확성을 기반으로 이를 명확하게 하는 방법에는 여러 가지 가능성이 있습니다.

int b((int(a))); int b((int)a);

대상을 그대로 선언해야합니다

X x(X::A);

코드의 버그.

이 두 줄 중 하나는 나에게 효과가 있습니다.

X obj(X::A);
X obj2 = X(X::A);

Neil Butterworth가 지적했듯이 X(X::A) 기능 선언으로 취급되고 있습니다. 익명의 대상을 정말로 원한다면 (X)(X::A) X 객체를 구성하고 즉시 삭제합니다.

물론 다음과 같은 일을 할 수 있습니다.

int main()
{
    // code
    {
    X temp(X::A);
    }
    // more code
}

이것은 더 읽기 쉽고 기본적으로 동일한 효과를 갖습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top