문제

나는 현재 C ++ 11의 기능을 배우려고 노력하고 있으며 Auto 및 Decltype에 어려움을 겪고 있습니다. 학습 운동으로서 나는 일반적인 기능으로 STD 클래스 목록을 확장하고 있습니다.

template<class _Ty, class _Ax = allocator<_Ty>>
class FList : public std::list<_Ty, _Ax>
{
public:
    void iter(const function<void (_Ty)>& f)
    {
        for_each(begin(), end(), f);
    }

    auto map(const function<float (_Ty)>& f) -> FList<float>*
    {
        auto temp = new FList<float>();

        for (auto i = begin(); i != end(); i++)
            temp->push_back(f(*i));

        return temp;
    }
};

auto *ints = new FList<int>();
ints->push_back(2);
ints->iter([](int i) { cout << i; });

auto *floats = ints->map([](int i) { return (float)i; });
floats->iter([](float i) { cout << i; });

멤버 맵의 경우 전달 된 함수가 반환하는 내용에 따라 리턴 유형이 일반적인 것으로 원합니다. 따라서 반환 유형의 경우 나는 이와 같은 일을 할 수 있습니다.

auto map(const function<float (_Ty)>& f) -> FList<decltype(f(_Ty))>*

또한 함수 템플릿에서 플로트 유형을 제거해야합니다.

auto map(const function<auto (_Ty)>& f) -> FList<decltype(f(_Ty))>*

템플릿 클래스를 사용할 수 있지만 리턴 유형을 지정해야하므로 인스턴스를 더욱 장점으로 만듭니다.

template<class T> FList<T>* map(const function<T (_Ty)>& f)

내 질문의 요약으로 템플릿 클래스를 사용하지 않고 맵을 정의하는 방법을 알아 내려고하지만 여전히 반환하는 유형의 일반적인 상태를 유지하려고합니다.

도움이 되었습니까?

해결책

파생 std::list 또는 기타 std:: 컨테이너는 낙담합니다.

반복기를 통해 모든 표준 컨테이너에서 작업 할 수 있도록 작업을 무료 기능으로 작성하십시오.

"템플릿 함수를 사용하지 않고 맵 정의"를 의미합니까?

당신은 그것을 사용할 수 있어야합니다 result_type 회원 유형 std::function 유형을 얻으려면 반환됩니다.

또한 함수가 std::function. 어떤 유형 으로든 열어두고 컴파일러가 모든 것을 결합하게 할 수 있습니다. 당신은 필요합니다 std::function 런타임 다형성.

그리고 새로운 것을 사용하여 원시 힙 할당 객체를 만들고 포인터로 반환하는 것은 Soooo 1992입니다! :)

당신의 반복 기능은 본질적으로와 동일합니다. 루프의 범위 기반.

하지만 그 모든 것 제쳐 ... 이와 같은 의미가 있습니까?

template <class TFunc>
auto map(const TFunc &f) -> FList<decltype(f(_Ty()))>*
{
    auto temp = new FList<decltype(f(_Ty()))>();

    for (auto i = begin(); i != end(); i++)
        temp->push_back(f(*i));

    return temp;
}

이것은 호출 가능한 모든 것이 일치하며 decltype를 사용하여 함수의 반환 유형을 파악합니다.

_ty는 기본 구성 가능이어야합니다. 인스턴스를 제조하여이를 해결할 수 있습니다.

template <class T>
T make_instance();

이를 호출하는 코드가 생성되지 않기 때문에 구현이 필요하지 않으므로 링커는 불평 할 것이 없습니다 (이를 지적 한 Dribeas 덕분에!)

그래서 코드는 이제 다음과 같습니다.

FList<decltype(f(make_instance<_Ty>()))>*

또는 말 그대로 _ty 인스턴스를 참조하여 함수 F를 호출함으로써 얻을 수있는 유형의 목록.

그리고 수락을위한 무료 보너스로서 rvalue 참조를 찾아보십시오 - 이것은 당신이 다음을 쓸 수 있음을 의미합니다.

std::list<C> make_list_somehow()
{
    std::list<C> result;
    // blah...
    return result;
}

그런 다음 다음과 같이 부릅니다.

std::list<C> l(make_list_somehow());

STD :: 목록에는 "이동 생성자"가 있습니다 (사본 생성자와 같이 인수가 임시와 같이 임시 일 때 선택된 경우 선택). 반환 값의 내용을 훔칠 수 있습니다. 즉 swap. 따라서 전체 목록을 복사하지 않습니다. (이것이 C ++ 0x가 순진하게 작성된 기존 코드를 더 빨리 실행하는 이유입니다. 많은 인기이지만 추악한 성능 트릭이 쓸모 없게 될 것입니다).

그리고 당신은 올바른 움직임 생성자를 사용하여 unique_ptr.

std::unique_ptr<MyThing> myThing(make_my_thing_somehow());

다른 팁

인수 유형을 추론하려는 기능 인수에서 자동 사용할 수 없습니다. 이를 위해 템플릿을 사용합니다. 다음을 살펴보십시오.http://thenewcpp.wordpress.com/2011/10/18/the-keyword-auto/ 그리고http://thenewcpp.wordpress.com/2011/10/25/decltype-and-declval/. 그들은 모두 자동 및 decltype를 사용하는 방법을 설명합니다. 그들은 당신에게 그들이 어떻게 사용되는지에 대한 충분한 정보를 제공해야합니다. 특히, make_instance에 대한 또 다른 답변은 Declval에서 더 잘 수행 될 수 있습니다.

나는 Jarrah가 그의 대답에서 만들었던 요점은 이러한 점이 이러한 것들을 사용하는 방법을 정확하게 설명한다는 것입니다. 어쨌든 세부 사항을 지적하겠습니다.

당신은 이것을 할 수 없습니다. 두 가지가 잘못되었습니다.

auto map(const function<auto (_Ty)>& f) -> FList<decltype(f(_Ty))>*

auto 기능 인수에는 사용할 수 없습니다. 함수 유형을 추론하려면 템플릿을 사용해야합니다. 두 번째는 그 것입니다 decltype 표현을 취합니다 _Ty 유형입니다. 다음은 해결 방법입니다.

template <typename Ret>
auto
map(const function<Ret (_Ty)>& f)
  -> FList<decltype(f(declval<_Ty>()))>
{}

그렇게하면 유형의 인스턴스를 만들 수있는 마법이 없습니다.

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