C++ 입문한지 얼마 안되 도움좀 청합니다.

조회수 420회

https://github.com/warren-126/RSJp-cpp/blob/master/RSJparser.tcc

// 파일내 305번째줄
template <class dataType>
     dataType as(const dataType& def = dataType()) { // specialized outside class declaration
         if (!exists()) return (def);
        return dataType(data); // default behavior for unknown types: invoke 'dataType(std::string)'
    }

JSon 문서 파싱을 위해 해당 파일을 include하고 사용중에 있는데 빌드가 안되서 질문드립니다...

  • 환경
    Toolset VC2019 v142
    Windows SDK 10.0

위에 구문에서 아래의 에러가 뜨는데...

Severity    Code    Description Project File    Line    Suppression State
Error   C2440   '<function-style-cast>': cannot convert from 'std::string' to 'dataType'
Severity    Code    Description Project File    Line    Suppression State
Error   C2064   term does not evaluate to a function taking 1 arguments

template datatype을 변형하는데 string만 변형할 수 없다는 에러메시지가 왜 발생하는지 알 수가 없습니다. 구글에 찾아봐도 검색능력 부족인지 결과가 잘 안나오네요...

혹시 짐작될 수 있는 단서 같은게 있을까요??

  • 해결은 했는데 dataType으로 float 쓰면 안되고 double만 쓸 수 있네요. float로 사용하려하면 해당 오류가 뜹니다. 은원기 2020.8.4 15:50

1 답변

  • 올려 주신 as() 함수 템플릿은 함수형 캐스팅을 통해 std::string 데이터를 변환하는 기본적인 내용으로 작성되어 있습니다. dataType이 std::string에 대한 변환 생성자 존재하거나, std::string이 dataType으로 캐스팅 연산자가 구현되어 있다면 as()는 정상적으로 컴파일 될 것입니다.

    dataType이 float 일 때를 생각해 보시면 float을 생성할 때 std::string을 인자로 받을 수 없습니다. std::string은 float으로의 캐스팅 연산자가 없습니다. 따라서 as()는 컴파일 될 수 없어 앞서 말씀하신 오류가 발생합니다.

    그렇다면 왜 double은 되는 걸까요?

    위에 올려주신 as()는 함수 템플릿은 일반화된 코드입니다. 따라서 템플릿 인자가 결정될 때 인스턴스화 되면서 템플릿 인자에 해당하는 as() 함수가 생성됩니다. 이러한 일반화된 내용이 아닌 특정 템플릿 인자에 대해서만 대응하는 내용을 작성하는 것을 특수화라고 합니다.

    https://github.com/warren-126/RSJp-cpp/blob/92f9502dbdc27dcffbd50f798d113411aa296abe/RSJparser.tcc#L744 의 내용을 보면 아래와 같으며, double에 대해서 as()를 특수화 하였습니다

    // double
    template <> inline 
    double  RSJresource::as<double> (const double& def) {
        if (!exists()) return (def);
        return (atof (strip_outer_quotes(data).c_str() ) );
    }
    

    앞선 일반화 코드와 다르게 atof를 이용하여 문자열을 실수로 변환하도록 코드가 작성되어 있습니다.

    따라서 템플릿 인자가 double일 때는 함수형 캐스팅이 아닌 atof를 이용하는 코드가 컴파일 됩니다.

    float의 경우 as()에 대한 특수화가 없기 때문에 일반화 코드가 적용되고 컴파일 오류가 발생합니다.

    https://github.com/warren-126/RSJp-cpp/blob/92f9502dbdc27dcffbd50f798d113411aa296abe/RSJparser.tcc 의 내용을 잘 보시면 bool, int 및 기타 타입에 대해서 특수화가 진행된 것을 확인 할 수 있습니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)