문제

잘 컴파일하고 잘 작동하는 다음 코드가 있습니다.

template<typename T>
T GetGlobal(const char *name);

template<>
int GetGlobal<int>(const char *name);

template<>
double GetGlobal<double>(const char *name);

그러나 "기본"기능을 제거하고 싶습니다. 즉, GetGlobal에 모든 전화를 걸고 싶습니다.u003Ct> 여기서 't'는 int가 아니거나 두 배의 오류가 아닙니다.

예를 들어, getGlobalu003Cchar> ()는 컴파일 타임 오류 여야합니다.

기본 기능을 삭제하려고했지만 상상했듯이 많은 오류가 발생했습니다. 그렇다면 기능의 특수 버전에만 호출을 허용하는 방법이 있습니까?

감사!

도움이 되었습니까?

해결책

컴파일 타임 오류를 얻으려면 다음과 같이 구현하십시오.

template<typename T>
T GetGlobal(const char *name) { T::unimplemented_function; }
// `unimplemented_function` identifier should be undefined

부스트를 사용하면 더 우아하게 만들 수 있습니다.

template<typename T>
T GetGlobal(const char *name) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }

C ++ 표준은 0과 같은 크기를 가진 유형이 없으므로 컴파일 타임 오류가 발생합니다.

처럼 SBI 그의 의견에서 마지막으로 마지막으로 줄일 수 있습니다.

template<typename T>
T GetGlobal(const char *name) { char X[!sizeof(T)]; }

첫 번째 솔루션은 다른 솔루션을 선호합니다. 왜냐하면 다른 솔루션은 다른 솔루션보다 더 명확한 오류 메시지 (적어도 시각적 C ++에서)를 제공하기 때문입니다.

다른 팁

오래되고 구식 질문이지만 주목할 가치가있을 수 있습니다. C++11 삭제 된 기능을 사용 하여이 문제를 해결했습니다.

template<typename T>
T GetGlobal(const char *name) = delete;

template<>
int GetGlobal<int>(const char *name);

업데이트

아래에서 컴파일되지 않습니다 MacOS llvm 8. 여전히 4 살짜리 결함이 매달려 있기 때문입니다 (참조 이 버그 보고서).

다음 해결 방법은 문제에 맞습니다 (사용 static_assert 건설하다).

template<typename T>
T GetGlobal(const char *name) {
    static_assert(sizeof(T) == 0, "Only specializations of GetGlobal can be used");
}

template<>
int GetGlobal<int>(const char *name);

업데이트

Visual Studio 15.9는 동일한 버그를 가지고 있습니다. 이전 해결 방법을 사용하십시오.

구현하지 않으면 최소한 링커 오류가 발생합니다. 컴파일 타임 오류를 원한다면 클래스 템플릿으로이를 수행 할 수 있습니다.

template<typename T>
struct GlobalGetter;

template<>
struct GlobalGetter<int> {
  static int GetGlobal(const char *name);
};

template<>
struct GlobalGetter<double> {
  static double GetGlobal(const char *name);
};

template<typename T>
T GetGlobal(const char *name)
{
  return GlobalGetter<T>::GetGlobal(name);
}

나는 실제로 구현을 제공하지 말고, 그 방법의 맨손 선언만을 제안합니다.

다른 옵션은 컴파일 타임 어제를 사용하는 것입니다. 부스트에는 많은 짐승이 있습니다.

namespace mpl = boost::mpl;
BOOST_MPL_ASSERT((mpl::or_< boost::same_type<T, double>,
                            boost::same_type<T, int> >));

메시지 버전도 있습니다.

다음은 부스트를 사용하는 대체 기술입니다.

typedef를 종속 이름으로 선언하십시오

이것은 'T'가 교체되었을 때만 발생하지 않기 때문에 작동합니다. 이것은 유사한 (그러나 합법적 인) 버전의 예제입니다. 키릴

template <typename T>
T GetGlobal (const char * name) {
    typedef typename T::DONT CALL_THIS_FUNCTION;
}

불완전한 반환 유형을 사용하십시오

이 기술은 전문화에 효과가 없지만 과부하에는 효과가 있습니다. 아이디어는 불완전한 유형을 반환하는 함수를 선언하는 것이 합법적이지만 호출하지 않는다는 것입니다.

template <typename T>
class DONT_CALL_THIS_FUNCTION GetGlobal (const char * name);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top