클래스 템플릿에서 상속되는 템플릿 매개 변수의 기본 템플릿 유형을 확인하는 방법은 무엇입니까?

user1777820

이것은 아마도 전에 묻고 대답했을 것입니다. 그러나 나는 그것을 찾기위한 검색어를 알아낼 수 없었습니다. 다음은 내 문제를 보여주는 코드입니다 (의사 코드로 의도 된 것입니다 ... 필요한 경우 설명을 요청하십시오).

Image.h :

template <class T>
class Image
{
    public:
        // Return pointer to data.
        T* GetValues(); 

        std::vector<T> data_;

};

template <class T>
T* Image<T>::GetValues()
{
    return &data_[0];
}

SpecialImage.h

class SpecialImage : public Image<float>
{

}

Stack.h

template<class T>
class Stack
{
    public:

        void NegateAllImageValues();

        std::vector<T> stackOfImages_;
};

template <class T>
void Stack::NegateAllImageValues()
{
    for(int i = 0; i < stackOfImages_.size(); ++i)
    {
        // Type L should be float if T=SpecialImage, but how to get?
        L* imageValues = stackOfImages_.at(i).GetValues(); 

        // Loop over values and multiply by -1.0.
    }
}

main.cpp

{
    // Create stack of SpecialImages.
    Stack<SpecialImage> myStack; 

    // Create special image and add some data.
    SpecialImage mySpecialImage; 
    mySpecialImage.data_.push_back(1.0f);
    mySpecialImage.data_.push_back(2.0f);
    mySpecialImage.data_.push_back(3.0f);

    // Add special image to stack.
    myStack.stackOfImages_.push_back(mySpecialImage);

    // Negate all values in all SpecialImages in the stack.
    myStack.NegateAllImageValues();

}

내 질문은 Stack :: NegateAllImageValues에서 유형 L을 아는 방법입니다. Image :: NegateAllValues ​​메서드를 작성하고 Stack :: NegateAllImageValues에서 호출 할 수 있다는 것을 알고 있지만 스택 수준에서 L 유형을 얻는 방법이 있는지 알고 싶습니다. Stack :: NegateAllImageValues ​​함수에 추가 템플릿 매개 변수를 추가 할 수 있다고 생각합니다.

template <class T, class L>
void Stack::NegateAllImageValues()
{
    for(int i = 0; i < stackOfImages_.size(); ++i)
    {
        // Type L should be float if T=SpecialImage, but how to get?
        L* imageValues = stackOfImages_.at(i).GetValues(); 

        // Loop over values and multiply by -1.0.
    }
}

그러나 유형 L은 이미지의 기본 템플릿 유형과 일치하도록 강제되지 않습니다.

여기에 고유 한 디자인 결함이 있습니까? 스택 수준에서 유형 L을 얻는 방법이 있습니까?

트리스탄 브린들

이를 수행하는 고전적인 방법은 Image클래스 에 typedef / alias를 넣는 것입니다.

template <typename T>
class Image {
public:
    typedef T value_type;

    // Other stuff
};

그런 다음 나중에 Stack::NegateAllImageValues()방법 에서 다음과 같이 말할 수 있습니다.

template <class T>
void Stack::NegateAllImageValues()
{
    for(int i = 0; i < stackOfImages_.size(); ++i)
    {
        typename T::value_type* imageValues = stackOfImages_.at(i).GetValues(); 

        // Loop over values and multiply by -1.0.
    }
}

이러한 종류의 typedef는 기본적으로 표준 라이브러리의 모든 템플릿 클래스에서 사용됩니다. 예를 들어 std::vector<T>.NET value_type의 별칭 인 멤버 typedef를 포함합니다 T.

C ++ 11 이상의 대안은 다음과 같이 auto대신 사용하는 것입니다.

template <class T>
void Stack::NegateAllImageValues()
{
    for(int i = 0; i < stackOfImages_.size(); ++i)
    {
        auto* imageValues = stackOfImages_.at(i).GetValues(); 

        // Loop over values and multiply by -1.0.
    }
}

[Plain auto도 똑같이 작동 auto*하지만 포인터 유형을 예상하고 있음을 분명히하기 때문에 후자를 선호합니다.]

마지막으로 C ++ 11에서는 다음 decltype과 같은 반환 유형을 가져 오는 데 사용할 수 있습니다 GetValues().

template <class T>
void Stack::NegateAllImageValues()
{
    for(int i = 0; i < stackOfImages_.size(); ++i)
    {
        using value_type = decltype(stackOfImages_.at(i).GetValues());
        value_type imageValues = stackOfImages_.at(i).GetValues(); 

        // Loop over values and multiply by -1.0.
    }
}

이것이 실제로 당신에게 아무것도 얻지 못하더라도 auto.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관