반환 유형별 오버로딩 연산자 오버로딩 등을 연구하지

나는 아직 나에게 혼란스러워 보이는이 주제에 대해 몇 가지 질문을 읽었습니다. 저는 방금 C ++를 배우기 시작했고 아직 템플릿이나 연산자 오버로딩 등을 연구하지 않았습니다.

이제 과부하하는 간단한 방법이 있습니다.

class My {
public:
    int get(int);
    char get(int);
}

템플릿이나 이상한 행동없이? 아니면 그냥

class My {
public:
    int get_int(int);
    char get_char(int);
}

?



답변

아니에요. 반환 유형에 따라 메서드를 오버로드 할 수 없습니다.

오버로드 해결은 함수 서명 을 고려합니다 . 함수 서명은 다음으로 구성됩니다.

  • 기능 명
  • cv 한정자
  • 매개 변수 유형

그리고 여기에 인용문이 있습니다.

1.3.11 서명

오버로드 해결 (13.3)에 참여하는 함수에 대한 정보 : 매개 변수 유형 목록 (8.3.5) 및 함수가 클래스 멤버 인 경우 함수 자체 및 클래스에 대한 cv 한정자 (있는 경우) 여기서 멤버 함수가 선언됩니다. […]

옵션 :

1) 메소드 이름 변경 :

class My {
public:
    int getInt(int);
    char getChar(int);
};

2) 출력 매개 변수 :

class My {
public:
    void get(int, int&);
    void get(int, char&);
}

3) 템플릿 …이 경우 과잉.


답변

가능하지만 초보자에게 추천 할 수있는 기술인지는 잘 모르겠습니다. 다른 경우와 마찬가지로 반환 값이 사용되는 방식에 따라 함수를 선택하려면 프록시를 사용합니다. 처음처럼 함수를 정의 getChar하고 getInt다음 일반 get()이 같은 프록시를 반환를 :

class Proxy
{
    My const* myOwner;
public:
    Proxy( My const* owner ) : myOwner( owner ) {}
    operator int() const
    {
        return myOwner->getInt();
    }
    operator char() const
    {
        return myOwner->getChar();
    }
};

필요한만큼 많은 유형으로 확장하십시오.


답변

아니요, 반환 유형으로 오버로드 할 수 없습니다. 매개 변수 유형 및 const / volatile 한정자에 의해서만.

한 가지 대안은 참조 인수를 사용하여 “반환”하는 것입니다.

void get(int, int&);
void get(int, char&);

나는 아마도 템플릿을 사용하거나 두 번째 예제와 같이 다른 이름의 함수를 사용할 것입니다.


답변

다음과 같이 생각할 수 있습니다.

당신은 :

  int get(int);
  char get(int);

그리고 호출하는 동안 함수의 반환 값을 수집하는 것은 필수가 아닙니다.

이제 당신은

  get(10);  -> there is an ambiguity here which function to invoke.

따라서 반환 유형에 따라 오버로딩이 허용되면 의미가 없습니다.


답변

오래된 스레드를 부활 시켰지만 아무도 ref 한정자에 의한 오버로딩을 언급하지 않았다는 것을 알 수 있습니다. Ref-qualifier는 C ++ 11에 추가 된 언어 기능이며 최근에야 우연히 발견했습니다. 예를 들어 cv-qualifiers처럼 널리 퍼져 있지는 않습니다. 주요 아이디어는 멤버 함수가 rvalue 객체에서 호출되는 경우와 lvalue 객체에서 호출되는 경우의 두 경우를 구분하는 것입니다. 기본적으로 다음과 같이 작성할 수 있습니다 (OP의 코드를 약간 수정하고 있습니다).

#include <stdio.h>

class My {
public:
    int get(int) & { // notice &
        printf("returning int..\n");
        return 42;
    }
    char get(int) && { // notice &&
        printf("returning char..\n");
        return 'x';
    };
};

int main() {
    My oh_my;
    oh_my.get(13); // 'oh_my' is an lvalue
    My().get(13); // 'My()' is a temporary, i.e. an rvalue
}

이 코드는 다음 출력을 생성합니다.

returning int..
returning char..

물론 cv 한정자의 경우와 마찬가지로 두 함수 모두 동일한 유형을 반환 할 수 있으며 오버로딩은 여전히 ​​성공적입니다.


답변

앞서 언급했듯이 템플릿은이 경우 과잉이지만 여전히 언급 할 가치가있는 옵션입니다.

class My {
public:
    template<typename T> T get(int);
};

template<> int My::get<int>(int);
template<> char My::get<char>(int);


답변

이 문제에 대한 다른 의견의 대부분은 기술적으로 정확하지만, 당신은 할 수 효과적으로 반환 값 과부하 경우 는 입력 매개 변수를 오버로드와 결합. 예를 들면 :

class My {
public:
    int  get(int);
    char get(unsigned int);
};

데모:

#include <stdio.h>

class My {
public:
    int  get(         int x) { return 'I';  };
    char get(unsinged int x) { return 'C';  };
};

int main() {

    int i;
    My test;

    printf( "%c\n", test.get(               i) );
    printf( "%c\n", test.get((unsigned int) i) );
}

결과는 다음과 같습니다.

I
C