>source

문자열 멤버 변수가 포함 된 클래스가 있고 문자열을 다른 유형으로 변환 할 수있는 템플리트 함수를 작성하려고합니다. 단순화 된 예로서 템플릿이없는 이는 내가 할 일입니다.

struct A {
    std::vector<std::string> tokens;
};
void Test(const A&amp;
 a) {
    //Get the final token value as an int, or default to 42.
    int i= a.tokens.empty() ? 42 : std::stoi(*a.tokens.rbegin());
}

이것은 최종 토큰을 얻으려고하고 구문 분석하려고하는 것처럼 많은 장소에서 작성하기 위해 지루해지기 때문에 다음을 썼습니다.

struct A {
    std::vector<std::string> tokens;
    const string&amp;
 GetLast(const string&amp;
 defaul= "") {
        return tokens.empty() ? defaul : *tokens.rbegin();
    }
    int GetLast(int defaul) {
        return tokens.empty() ? defaul : std::stoi(*tokens.rbegin());
    }
    float GetLast(float defaul) {
        return tokens.empty() ? defaul : std::stof(*tokens.rbegin());
    }
};
void Test(const A&amp;
 a) {
    int i= a.GetLast(42);
}

이것은 잘 작동하지만 템플리트로 묻는 것으로 묻는 것으로 보이며 컨버터 기능이 제공되는 모든 종류의 유형으로의 변환을 허용하는 것으로 보입니다. 그러나 나는 일을하는 일반적인 솔루션을 찾을 수없는 것 같습니다. 다음은 내가 작동해야한다고 생각할 수있는 가장 가까운 일이지만 템플릿 유형을 추론 할 수없는 컴파일러 오류를 지속적으로 얻을 수 있습니다.

template <typename T, typename Converter, typename... Args>T GetLastAs(T defaul, Args ...args)
{
    return tokens.empty() ? defaul : Converter(*tokens.rbegin(), args...);
}

사용량A.GetLastas < float, std :: Stof > (42.0f)

이 문제에 대한 일반적인 해결책이 있거나, 내 부품에 대한 희망적 사고가 있습니까?

함수 템플릿은 왜 VARIADIC입니까? 변환기는 무엇입니까?

463035818_is_not_a_number2021-09-20 09:45:12
  • 답변 # 1

    문자열을std :: ostringstream를 사용하여 값을 변수로 추출하고 값을 추출하십시오> >운영자.

    와 같이

    T value{};
    std::ostringstream{ string_to_convert } >> value;
    

    물론이 필요합니다NS기본적으로 구성 할 수 없으며,> >운영자가 정의했습니다NS...에


    IICS는 작품 (또는 적어도 작동하는 데 사용)의 방법입니다. 프로젝트에서 이미 부스트를 사용하는 경우, 직접 만드는 대신 어휘 캐스트 라이브러리를 사용하는 것이 좋습니다.

  • 답변 # 2

    문자열 스트림을 사용하여 다음과 같이 기본 구성 가능한 유형의 값을 추출할 수 있습니다.

    #include <string>#include <sstream>#include <iostream>template <typename T>T GetAs(const std::string&amp;
     s) {
        std::stringstream ss{s};
        T t;
        ss >> t;
        return t;
    }
    int main() {
        std::string s{"3.5"};
        std::cout << GetAs<int>(s) << "\n";
        std::cout << GetAs<double>(s) << "\n";
        std::cout << GetAs<std::string>(s) << "\n";
    }
    

    기본값과 문자열이 벡터의 요소라는 사실은 제쳐두고, 이는 솔루션에 필수적이지 않기 때문입니다.

    stringstream을 사용하면 1,2,3의 문자열을 array또는 glm::vec3으로 변환하려는 경우와 같이 임의의 유형으로 변환할 수 있습니까? 내 자신의 >>연산자 오버로드를 작성해야 한다고 가정합니다.

    Chris2021-09-20 09:45:12

    별도의 질문으로 stof 및 stoi는 문자열에 표시된 숫자의 기수를 지정하기 위한 추가 매개변수를 제공합니다. float 또는 int로 변환될 때 추가 매개변수를 어떻게 지정합니까? 이것이 내가 원래 예에서 가변 템플릿을 사용했던 이유입니다.

    Chris2021-09-20 09:45:12

    @Chris "변환기 기능"이 의미하는 바를 잘 이해하지 못합니다. 예, ss >>t를 만들려면 std::istream&operator>>(std::istream&,T&)가 있어야 합니다. 일하다. std::array(적어도 직접적으로는 아님)에 대해 operator>>를 오버로드하지 않는 것이 좋습니다. 질문이 stoX 제품군의 변환에 대해서만 언급하기 때문에 나는 이것을 고려하지 않았습니다.

    463035818_is_not_a_number2021-09-20 09:45:12

    @Chris btw 귀하의 질문에있는 변환기에 대한 혼란스러운 점은 그것이 함수라고 말하지만 code에서는 유형이라는 것입니다. Converter(*tokens.rbegin(), args...)는 생성자 호출입니다(그리고 code가 작동하려면 Converter를 T로 변환할 수 있어야 함)

    463035818_is_not_a_number2021-09-20 09:45:12

    @Chris 흠 ... 실제로 원하는 것에 달려 있습니다. float 및 int로 변환하려는 경우 템플릿으로 만들 이유가 없습니다. (작은) 제한된 유형 집합의 경우 일반적으로 오버로드가 더 쉬운 대안입니다. 어떤 전환을 사용하시겠습니까?

    463035818_is_not_a_number2021-09-20 09:45:12
  • 이전 pandas : 팬더를 사용하여 특정 컬럼의 평균을 취합니다
  • 다음 javascript : reducer의 유형 문제, useReducer가 있는 typescript