C 언어의 Member Detector이라는 관용구를 보았습니다.이 특성은 클래스에 특정 이름의 멤버가 있는지 알려주는 유형 특성입니다. 그러나 형식이 클래스가 아닌 경우 기대했던대로 링크 된 예제가 작동하지 않습니다. 모든 클래스가 아닌 형식에 대해 false
결과를 원했습니다. 가능한 해결책은 확실히 boost::is_class<T>
를 사용하여이 같은입니다 :SFINAE 유형의 인스턴스화
template<typename T>
struct general_DetectX : boost::mpl::and_<
boost::is_class<T>,
DetectX<T> >::type
{ };
bool hasX = general_DetectX<int>::value; // hasX = false
그러나이 질문은 원래 DetectX<T>
대신 SFINAE 일을하는 오류를 발생 이유에 관한 것입니다. 여기에 연결된 코드의 관련 부분의 발췌가 (간략화를 위해 제거 로컬 구조체 Fallback
및 Check<U,U>
및 형식 정의 ArrayOfOne
, ArrayOfTwo
및 type
)
template<typename T>
class DetectX
{
struct Derived : T, Fallback { };
template<typename U>
static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
template<typename U>
static ArrayOfTwo & func(...);
public:
enum { value = sizeof(func<Derived>(0)) == 2 };
};
그것은
DetectX::Derived
것을 알 수
모든 오버로드 해결 밖에 사용 , 오류 처리를위한 SFINAE 규칙이 호출되지 않습니다. 그러나 이것은 Derived
의 사용가 오버로드 확인의 일환으로 일어날 않는 경우에 변경 될 수 있습니다
template<typename T>
class DetectX
{
template<typename U>
struct Derived : U, Fallback { };
template<typename U>
static ArrayOfOne & func(Check<int Fallback::*, &Derived<U>::X> *);
template<typename U>
static ArrayOfTwo & func(...);
public:
enum { value = sizeof(func<T>(0)) == 2 };
};
Derived<T>
템플릿을 처음 func()
과부하를 인스턴스화 할 때에만 인스턴스화, 왜 난 여전히 오류를받을 수 있나요 수정 된 버전의 경우에도?
$ g++ --version | head -n1
g++ (GCC) 4.8.2
$ g++ -c demo.cxx
demo.cxx: In instantiation of 'struct DetectX<int>::Derived<int>':
demo.cxx:16:53: required by substitution of 'template<class U> static char (& DetectX<T>::func(DetectX<T>::Check<int DetectX<T>::Fallback::*, (& DetectX<T>::Derived<U>::X)>*))[1] [with U = U; T = int] [with U = int]'
demo.cxx:24:31: required from 'class DetectX<int>'
demo.cxx:27:25: required from here
demo.cxx:7:12: error: base type 'int' fails to be a struct or class type
struct Derived : U, Fallback { };
^
기본 클래스 목록에서 대체가 발생하기 때문에 오류가 발생합니다. * 모든 오류로 인해 소프트 오류 (SFINAE)가 아닌 오류가 발생합니다. 즉, 기본 클래스에서는 SFINAE가 발생하지 않습니다. – Nawaz
@Nawaz 하드 및 소프트 오류를 소개하는 의견을 보내 주셔서 감사합니다. 그러나 Jarod42가 제공 한 http://stackoverflow.com/questions/15260685에 대한 링크가 필요하여 문맥을 얻으 려했습니다. –