SFINAE가 "has_member"유형의 구조체에 적용되어 놀았습니다 (here).is_enum이 잘못된 동작을 일으키는 경우?
그래서이 솔루션을 더 간단하게 만들기 위해 C++ 11의 일부 기능을 사용하려고했습니다. 열거 형의 존재 여부를 확인하는 데 몇 가지 문제가 있지만 여기서 논리 오류를 찾을 수 없습니다. 이 사용 GCC 4.9.2을 실행
#include<iostream>
template<typename T >
struct has_enum_name
{
private:
// ***** this is the line that isn't working *****
// If U has an enum "name", then I expect is_enum to return true…
// Then I expect enable_if<>::type to be std::true_type…etc. This isn't what happens.
template<typename U> static auto test(int) -> decltype(
std::enable_if<std::is_enum< typename U::name >::value, std::true_type>::type());
template<typename U> static auto test(...) -> std::false_type;
public:
static constexpr bool value =
!(std::is_same<decltype(test<T>(0)),std::false_type>::value);
static constexpr bool is_enum()
{
return std::is_enum<typename T::name>::value;
}
};
template<typename T >
struct has_enum_name_2
{
private:
template<typename U> static auto test(int) -> decltype(
std::enable_if<true, std::true_type>::type());
template<typename U> static auto test(...) -> std::false_type;
public:
static constexpr bool value =
!(std::is_same<decltype(test<T>(0)),std::false_type>::value);
};
struct Foo
{
enum class name
{
enum1,
enum2
};
};
int main()
{
std::cout<<"std::is_enum<Foo::name>::value = "<<std::is_enum<Foo::name>::value<<std::endl;
std::cout<<"has_enum_name<Foo>::value = "<<has_enum_name<Foo>::value<<std::endl;
std::cout<<"has_enum_name<Foo>::is_enum() = "<<has_enum_name<Foo>::is_enum()<<std::endl;
std::cout<<"has_enum_name_2<Foo>::value = "<<has_enum_name_2<Foo>::value<<std::endl;
}
첫 번째 출력 라인은 표준 : is_enum는 푸 :: 이름을 열거 올바르게 작동하는지 확인
$ ./a.out
std::is_enum<Foo::name>::value = 1
has_enum_name<Foo>::value = 0
has_enum_name<Foo>::is_enum() = 1
has_enum_name_2<Foo>::value = 1
제공 : 코드입니다.
두 번째 줄은 struct constexpr "has_enum_name :: value"의 결과를 출력합니다. 난 그냥 std :: enable_if 함께 std :: is_enum decltype 반환 할 수 있도록 사용하려고 ...이 경우 std :: true_type(). 보시다시피, 출력은 false를 반환합니다 ... 그래서 줄 :
template<typename U> static auto test(int) -> decltype(
std::enable_if<std::is_enum< typename U::name >::value, std::true_type>::type());
내가 생각하는 것처럼 작동하지 않습니다. 나는 is_enum이 true를 반환해야한다고 생각하는데, 이는 enable_if가 true_type을 반환해야하고 decltype이 true_type()을 반환해야 함을 의미합니다.
다음 출력은 std :: is_enum <이 구조체에서 올바르게 작동하는지 확인하는 것입니다. 그렇습니다.
다음 출력은 "has_enum_name"구조체의 복사본이지만 의심되는 줄의 is_enum <을 하드 코딩 된 "true"로 바꿨습니다. 올바르게 작동합니다.
그래서 어떤 이유로 is_enum이 true를 반환하지 않는 것으로 보입니다. 어떤 아이디어가 내가 여기서 잘못하고있는 것인가?
안녕하세요. (...)을 (를) 삭제 해 주셔서 감사합니다. 진짜 질문은 "SFINAE를 어떻게 디버깅해야합니까?"라는 질문이 있어야합니다.내가 아직도 혼란스러워하는 이유는 "std :: enable_if :: type"이 typename을 필요로하지 않고 "std :: enable_if :: value, std :: true_type> :: type; " 않습니다. –
doc07b5
@ doc07b5'std :: enable_if :: type'은 템플릿 매개 변수에 종속되지 않으므로 컴파일러는 템플릿을 파싱 할 때 유형임을 알 수 있습니다. 'std :: enable_if :: value, std :: true_type> :: type'은 템플릿 매개 변수'U'에 의존하기 때문에 컴파일러에게 예상하고 있다고 말할 필요가 있습니다 그것은 항상'typename' 키워드를 가진 타입을 산출합니다. –
Casey