문제

템플릿 함수 "foo"가 있다고 가정 해 봅시다.

template<class T>
void foo(T arg)
{ ... }

나는 특정 유형에 대해 전문화 할 수 있습니다.

template<>
void foo(int arg)
{ ... }

모든 내장 숫자 유형 (int, float, double 등)에 동일한 전문화를 사용하고 싶다면 해당 라인을 여러 번 쓸 것입니다. 나는 신체가 다른 기능으로 던져 질 수 있다는 것을 알고 있으며, 단지 모든 전문화의 신체에서 이것을 부르는 것만으로도 만들어야하지만,이 "void foo (...”모든 유형에 대한 글을 쓰지 않으면 더 좋을 것입니다. 이 모든 유형 에이 전문화를 사용하고 싶은 컴파일러를 알릴 가능성이 있습니까?

도움이 되었습니까?

해결책

당신은 사용할 수 있습니다 std::numeric_limits 유형이 숫자 유형인지 확인하려면 (is_specialized 모든 플로트 및 정수 기본 유형에 맞습니다).

// small utility
template<bool> struct bool2type { };

// numeric
template<typename T>
void fooImpl(T arg, bool2type<true>) {

}

// not numeric
template<typename T>
void fooImpl(T arg, bool2type<false>) {

}

template<class T>
void foo(T arg)
{ fooImpl(arg, bool2type<std::numeric_limits<T>::is_specialized>()); }

다른 팁

사전 처리기와 함께 접근 방식을 사용할 수 있습니다.

foo.inc :

template<>
void foo(TYPE arg)
{ /* do something for int, double, etc. */ }

foo.h :

template<class T>
void foo(T arg)
{ /*do something */ }

#define TYPE int
#include "foo.inc"
#undef TYPE

#define TYPE double
#include "foo.inc"
#undef TYPE

등.

부스트와 함께 :

#include <boost/type_traits/is_scalar.hpp>
#include <iostream>
#include <string>

namespace detail
{
    typedef const boost::true_type& true_tag;
    typedef const boost::false_type& false_tag;

    template <typename T>
    void foo(const T& pX, true_tag)
    {
        std::cout << "special: " << pX << std::endl;
    }

    template <typename T>
    void foo(const T& pX, false_tag)
    {
        std::cout << "generic: " << pX << std::endl;
    }
}

template <typename T>
void foo(const T& pX)
{
    detail::foo(pX, boost::is_scalar<T>());
}

int main()
{
    std::string s = ":D";
    foo(s);
    foo(5);
}

부스트없이 대부분 쉽게 할 수 있습니다.

#include <iostream>
#include <string>

// boolean stuff
template <bool B>
struct bool_type {};

typedef bool_type<true> true_type;
typedef bool_type<false> false_type;

// trait stuff
template <typename T>
struct is_scalar : false_type
{
    static const bool value = false;
};

#define IS_SCALAR(x) template <> \
            struct is_scalar<x> : true_type \
            { \
                static const bool value = true; \
            };

IS_SCALAR(int)
IS_SCALAR(unsigned)
IS_SCALAR(float)
IS_SCALAR(double)
// and so on

namespace detail
{
    typedef const true_type& true_tag;
    typedef const false_type& false_tag;

    template <typename T>
    void foo(const T& pX, true_tag)
    {
        std::cout << "special: " << pX << std::endl;
    }

    template <typename T>
    void foo(const T& pX, false_tag)
    {
        std::cout << "generic: " << pX << std::endl;
    }
}

template <typename T>
void foo(const T& pX)
{
    detail::foo(pX, is_scalar<T>());
}

int main()
{
    std::string s = ":D";
    foo(s);
    foo(5);
}

어쩌면 모든 기본 유형에서 작동하는 기본 템플릿 기능을 정의하고 사용자에게 사용자 정의 유형의 전문화를 위임 할 수 있습니다.

작은 스크립트 (예 : Perl)를 작성하여 소스 파일을 생성 할 수 있습니다. 전문화하려는 모든 유형이 포함 된 배열을 만들고 각각의 함수 헤더를 작성하도록하십시오. MakeFile에 스크립트 실행을 포함시켜 무언가를 변경하면 자동으로 다시 실행할 수도 있습니다.

참고 : 이것은 구현을 가정합니다 foo 예를 들어 각 유형에 대해 사소하고 유사하게 만들 수 있습니다. 그러나 그것은 미래의 관리자가 머리를 긁을 수있는 템플릿/사전 처리기 Mumbo-Jumbo를 피합니다.

요하네스 솔루션의 개선은 다음과 같습니다. 그러나 읽기 쉽습니다. 함수 내부에서 유형을 확인하십시오.

template<typename T>
void foo(T arg)
{
  if (numeric_limits<T>::is_specialized)  // not a runtime check - compile time constant
  {
  }
  else
  {
  }
}

유형 특성 사용 (자체 템플릿 전문화)

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