>백엔드 개발 >C++ >SFINAE가 클래스 템플릿 멤버 기능에 실패하는 이유는 무엇입니까?

SFINAE가 클래스 템플릿 멤버 기능에 실패하는 이유는 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-04 22:18:02809검색

Why Does SFINAE Fail for Class Template Member Functions?

클래스 템플릿 멤버 함수에 대한 SFINAE 실패

SFINAE(대체 실패, 오류가 아님) 메커니즘은 템플릿 메타프로그래밍에 일반적으로 사용됩니다. 클래스 템플릿 멤버 함수에 적용하면 특이한 동작을 보이는 것으로 보입니다.

문제

다음 코드 조각을 고려하세요.

<code class="cpp">#include <type_traits>

struct A{};
struct B{};

template <typename T>
struct Foo
{
    // Conditional enable bar() for T == A
    typename std::enable_if<std::is_same<T, A>::value>::type
    bar()
    {}

    // Conditional enable bar() for T == B
    typename std::enable_if<std::is_same<T, B>::value>::type
    bar()
    {}
};</code>

이 코드 Foo 클래스 템플릿에서 bar()의 두 오버로드를 정의하려고 시도합니다. SFINAE는 T 값을 기반으로 각 오버로드를 조건부로 활성화하는 데 사용됩니다. 그러나 다음 오류로 인해 코드가 컴파일되지 않습니다.

<code class="cpp">error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded</code>

설명

SFINAE는 일반적으로 템플릿 인수를 기반으로 템플릿 특수화를 활성화하거나 비활성화하는 데 사용됩니다. 그러나 SFINAE는 추론된 템플릿 인수에만 적용됩니다. 즉, 오버로드 해결 중에 자동으로 추론되는 인수를 의미합니다. 멤버 함수의 경우 템플릿 인수는 추론되지 않고 클래스를 인스턴스화할 때 명시적으로 지정됩니다. 따라서 SFINAE는 멤버 함수에는 적용되지 않습니다.

해결책

이 문제를 해결하는 방법은 크게 두 가지가 있습니다.

  • 함수 템플릿 사용: 아래와 같이 각 오버로드에 대해 별도의 함수 템플릿을 정의합니다.
<code class="cpp">template <typename T>
void bar(Foo<T><- A) {}

template <typename T>
void bar(Foo<T><- B) {}
  • 명시적 클래스 템플릿 전문화 사용: 별도 정의 아래와 같이 각 오버로드에 대한 클래스 템플릿:
<code class="cpp">template <typename> struct Foo;

template <> struct Foo<A> { void bar() {} };
template <> struct Foo<B> { void bar() {} };</code>

위 내용은 SFINAE가 클래스 템플릿 멤버 기능에 실패하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.