C ++ 템플릿 클래스를 전달하는 방법은 무엇입니까?


101

다음과 같은 템플릿 클래스가 제공됩니다.

template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

누군가가 헤더 파일에서이 클래스를 어떻게 앞으로 선언 할 수 있습니까?

답변:


104

이것은 당신이 그것을하는 방법입니다.

template<typename Type, typename IDType=typename Type::IDType>
class Mappings;

template<typename Type, typename IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

기본값은 실제 정의가 아닌 정방향 선언에 있습니다.


정의에 기본값이 나열된 클래스를 포워드 선언 할 수 있습니다. 내 대답을 참조하십시오.
Elliott

동의하지 않습니다. 표준에 따르면 "템플릿 매개 변수는 동일한 범위에서 두 개의 다른 선언에 의해 기본 인수가 주어지지 않습니다" . 그리고 첫 번째 선언에서만 기본값에 대해 아무것도 발견하지 못했습니다. 또한 정의에 정방향 선언 및 기본값이있는 코드가 성공적으로 컴파일되고 실행됩니다. 당신이 주장하는 것에 대해 확신합니까? 표준 견적을 제공 할 수 있습니까?
olek stolar

@Elliott 사실 인 것 같습니다. 표준 [17.1.9]에는 "기본 템플릿 인수 템플릿 선언에 지정 될 수 있습니다 . " 라고 말합니다 . 반드시 그럴 필요는 없지만 그럴 수도 있습니다. 따라서 다른 답변이 첫 번째 선언에 있어야한다고 주장하는 이유를 이해하지 못합니다.
olek stolar

그리고 정의에 기본값을 사용하는 것이 훨씬 더 편리한 것 같습니다.
olek stolar

8

템플릿의 첫 번째 선언에 대해서만 템플릿에 대한 기본 인수를 선언 할 수 있습니다. 사용자가 클래스 템플릿을 전달하도록 허용하려면 전달 헤더를 제공해야합니다. 기본값을 사용하여 다른 사람의 클래스 템플릿을 전달하고 싶다면 운이 좋지 않습니다!


정의에 기본값이 나열된 클래스를 포워드 선언 할 수 있습니다. 내 대답을 참조하십시오.
Elliott

동의하지 않습니다. 표준에 따르면 "템플릿 매개 변수는 동일한 범위에서 두 개의 다른 선언에 의해 기본 인수가 주어지지 않습니다" . 그리고 첫 번째 선언에서만 기본값에 대해 아무것도 발견하지 못했습니다. 또한 정의에 정방향 선언 및 기본값이있는 코드가 성공적으로 컴파일되고 실행됩니다. 당신이 주장하는 것에 대해 확신합니까? 표준 견적을 제공 할 수 있습니까?
olek stolar

3

당신은 할 수 있습니다 누구의 정의 기본 인수를 내용의 템플릿 클래스를 선언하지만, 정의가 도입 될 때까지 클래스를 참조하는 모든 시간을 당신은 모든 인수를 포함해야합니다.

예. std::vector포함하지 않고 사용합시다 (의 두 번째 인수 std::vector는 기본값으로 정의 됨).

namespace std
{
    template<typename, typename>
    class vector;
}

#include <iostream>

template <typename S, typename T>
void Foo (const std::vector<S,T> & vector)
{
    std::cout << "do vector stuff, eg., display size = "
        << vector.size() << std::endl;
}

template <typename T>
void Foo (const T & t)
{
    std::cout << "do non-vector stuff..." << std::endl;
}

그런 다음 벡터를 포함하지 않고 사용할 수 있습니다. 예 :

int main()
{
    Foo(3);
}

그리고 우리는 그것을 사용할 수 있습니다 std::vector , 예를 들면 :

#include <vector>

// Now the compiler understands how to handle
// std::vector with one argument
// (making use of its default argument)

int main()
{
    Foo(std::vector<int>(3));
}

나는 표준 만에이 작품을 선택하지 않은 clang/ gcc-std=c++98최대를 -std=c++17그 다음 공식 표준이 아니다는 비공식적으로 너무 것 같아요 그렇다면,.


빈 꺾쇠 괄호를 잊어 버릴 수도 있습니다 Foo<> foo;.
olek stolar

@ OleksijPlotnyc'kyj 맞아요. 감사. 그 추가를 삭제했습니다.
Elliott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.