2017-10-11 9 views
0

~ 30 개의 다양한 데이터 유형 필드가 포함 된 private struct 멤버가있는 Eclipse 클래스가 있습니다.메서드 호출을 기반으로 변경 될 후행 반환 형식의 메서드를 작성 하시겠습니까?

매개 변수로 전달 된 필드 번호를 기반으로 구조체에서 데이터 필드를 반환하는 메서드가 있습니다.

구조체에 다양한 유형의 데이터가 포함되어 있으므로 템플릿 기반 매개 변수를 기반으로 후행 반환 형식으로 auto 키워드를 사용하기로 선택했습니다. 내 메소드 헤더는 아래와 같습니다. 내가 int하는 열을 반환하려면

template<typename TheType> 
auto getColumnData(TheType toGet, int fieldNum) -> decltype(toGet) { 
    // switch statement to return fields based on fieldNum 
} 

, 나는 getColumnData(0, 1);를 호출합니다. 첫 번째 매개 변수는 메서드의 반환 형식을 결정하는 데만 사용되며 두 번째 매개 변수는 메서드 호출자에게 반환 할 필드 번호를 결정합니다.

이론적으로이 경우 반환 유형은 getColumnData()int이고 구조체의 첫 번째 열 (첫 번째 필드에 해당)을 반환합니다. 내가 첫 번째 매개 변수로 int이 방법과 std::string을 반환 필드에 해당하는 필드 번호로 전화를한다면,이있을 것이라는 점을 이해

no viable conversion from returned value of type 'std::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') to function return type 'decltype(toGet)' (aka 'int')`

:하지만이 컴파일 오류가 발생 해요 문제. 그러나 다른 클래스의 수표를 기반으로이 경우는 절대로 발생하지 않습니다.

특정 경우에 맞지 않을지라도 컴파일러가이 코드를 받아 들일 수있는 방법이 있습니까?

나는 단지 메서드가 오버로드 될 수 있음을 알고 있지만, 하나의 태스크 만 수행하는 방법을 파악할 수 있다면 기본적으로 같은 목적으로 여러 가지 메서드를 사용하지 않을 것입니다.

또한이 정보에 대한 이해가 잘못되었다고 생각되면 알려 주시기 바랍니다. 저는 C++을 처음 접했을뿐입니다. 그래서이 기능들을 배우는 것입니다.

+0

이것은 완전히 잘못되었습니다. 첫 번째 매개 변수가'int' 인 경우'decltype'은 함수가 정의에 따라'int'를 리턴하도록 지정합니다. 마침표. 이야기의 끝. 그 점에서 쓴 다른 모든 것은 부적절합니다. 인스턴스화 된 템플릿 함수는 'int', ifs, ands 또는 buts를 반환해야합니다. –

답변

0

시도하는 것처럼 런타임에 메서드의 반환 유형을 동적으로 변경할 수 없습니다. 첫 번째 매개 변수는 컴파일시 알려진 데이터 유형이 아닙니다. 이것은 런타임시 채워지는 정수이므로, 컴파일 타임 결정을 전혀 내릴 수 없습니다. 그렇지

using FieldType = std:::variant<int, std::string>; 

FieldType getColumnData(int fieldNum) { 
    // switch statement to return fields based on fieldNum 
} 

int i = std::get<int>(getColumnData(1)); 
std::string s = std::get<std::string>(getColumnData(2)); 

:

간단한 해결책은 복귀 형으로 std::variant (C++ 17 이상) 또는 boost::variant (C++ 11 이상)을 사용하는 것 반환 형식을 메서드 매개 변수가 아닌 템플릿 매개 변수로 설정해야합니다.

template<typename TheType> 
TheType getColumnData(int fieldNum) { 
    // switch statement to return fields based on fieldNum 
} 

그러나 모든 필드가 반환 유형으로 변환 될 수는 없다는 문제가 발생합니다 (int 등이 요청되면 std::string 필드를 반환 할 수 없음). 은 fieldNum이 아니므로 컴파일 타임에 평가된다.

당신은 컴파일 시간에 일정 수 있도록 필드 번호가 템플릿 매개 변수가 될 수 있도록 한 다음에 전문 유혹 될 수

:

template<const int FieldNum> 
auto getColumnData() { return 0; }; 

template<> int getColumnData<1>() { return private_struct.Field1; } 
template<> std::string getColumnData<2>() { return private_struct.Field2; } 
// etc... 

int i = getColumnData<1>(); 
std::string s = getColumnData<2>(); 

하지만 오류를 얻을 템플릿 클래스 메서드 ("네임 스페이스 범위가 아닌 명시 적 특수화")에서이를 수행하려고 할 때.

당신이 뭔가를 할 유혹하고, 컴파일러가 사용되지 않는 지점 멀리 최적화 희망 될 수 있습니다

template<const int FieldNum> 
auto getColumnData() { 
    if (FieldNum == 1) return private_struct.Field1; 
    if (FieldNum == 2) return private_struct.Field2; 
    //etc... 
    return 0; 
} 

또는

template<const int FieldNum> 
auto getColumnData() 
{ 
    switch (FieldNum) { 
     case 1: return private_struct.Field1; 
     case 2: return private_struct.Field2; 
     // etc... 
    } 
    return 0; 
}; 

int i = getColumnData<1>(); 
std::string s = getColumnData<2>(); 

하지만 그건 '아무튼를 ("자동 반환 유형에 대한 일관성없는 공제"오류).