2013-04-21 3 views
1

하나의 인수로 생성자를 감지하는 방법을 아는 사람 있습니까? 내가 여기 있는지 볼 수있는 좋은 SFINAE 검사를SFINAE - 하나의 인수로 생성자 감지

struct MyStruct 
{ 
    MyStruct(int x, int x2) : y(x) {} 
    int y; 
}; 

특정 수의 인수를 가진 생성자와 같은 클래스 또는 구조체 : 예를 들어,이 구조체는 부정적인 결과가 있어야한다. Any 구조체 매개 변수가되어야한다 어떤 유형으로 변환 할 수 있습니다로,

template <typename T> 
struct HasCtor3Args 
{ 
    struct Any { template <typename U> operator U(void); }; 

    template <typename U> 
    static int32 SFINAE(decltype(U(Any(), Any(), Any())) *); 

    template <typename U> 
    static int8 SFINAE(...); 

    static const bool value = sizeof(SFINAE<T>(NULL)) == sizeof(int32); 
}; 

이 잘 작동하는 것 같다 : 여기에 3의 인수 개수의 하나입니다. 그러나 문제는 단 하나의 인수로 생성자를 탐지하려고 할 때입니다. SFINAE 검사는 과 같은 형식의 기본값 인 Any이 항상 복사 생성자를 감지하므로 항상 true로 반환됩니다.

편집 및 업데이트 : 내가 만든 한 몇 가지 시도는, 아무도는이 내가 얻을 수있는 가장 가까운이었다 ... 이동하지만, 항상 true를 돌려주는대로 작동하지 않는 것 같다 없습니다. 아이디어는 대신에 최초의 "모든 잡아"전화의 해결을 위해 복사 생성자를 시도하고 얻을 수 있었다 : 나는 또한 다음, C++ (11)에 대한 삭제 =와 함께 기능을 명시 적 키워드를 사용하여 시도

template <typename T> 
struct HasCtor1Args 
{ 
    struct Any 
    { 
    template <typename U> 
    operator U() const; 
    }; 

    template <typename U> 
    static int32 SFINAE(decltype(U(Any())) *); 

    // Try to catch the copy ctor here 
    T MakeT(void); 
    template <typename U> 
    static int8 SFINAE(decltype(U(MakeT())) *); 

    template <typename U> 
    static int8 SFINAE(...); 

    static const bool value = sizeof(SFINAE<T>(NULL)) == sizeof(int32); 
}; 

컴파일러를 깨달았습니다. (Microsoft의) 이것을 사용하지 않아도됩니다. 또한 함수 템플릿 매개 변수를 기본값으로 설정할 수 없다는 오류가 발생했지만 변환 유형 U에서 std :: enable_if를 사용하여 시도했습니다.

+0

그것은 매우 제한된 솔루션입니다 예를 들어 my_type(int, double=0);을 (애매함에 오를 초래하고있다 ['표준 : is_constructible'] (HTTP : // EN .cppreference.com/w/cpp/types/is_constructible) – dyp

+0

어떤 이유로 변환 연산자가 명시적일 때 작동합니다 :'template 명시 적 연산자 U() const;'. 표준,하지만 g ++ 4.8 버그가있을 수 있습니다. – dyp

+0

흠 나는 명시 적으로 Microsoft의 컴파일러에서 작동하는 것 같아요. – RandyGaul

답변

2

비록 n.m.의 비판은 여전히 ​​있지만 여기에는 으로만 유형을 감지하는 버전이 있으며 1 매개 변수가 아닌 비 복사, 이동하지 않는 ctor입니다. SFINAE를 사용하여 Any의 변환을 제한합니다.

참고 :.. 기본 인수를 추가 ctors가

#include <cstdint> 
#include <type_traits> 

template <typename T> 
struct HasCtor1Args 
{ 
    struct Any 
    { 
     template 
     < 
     typename U, typename SFINAE = 
      typename std::enable_if< false == std::is_same<U,T>::value, U >::type 
     > 
     operator U() const; 
    }; 

    template <typename U> 
    static int32_t SFINAE(decltype(U(Any())) *); 

    template <typename U> 
    static int8_t SFINAE(...); 

    static const bool value = sizeof(SFINAE<T>(nullptr)) == sizeof(int32_t); 
}; 


struct my_type 
{ 
    my_type(int); 
    my_type(my_type const&); 
}; 

int main() 
{ 
    static_assert(HasCtor1Args<my_type> :: value, "epic fail"); 
} 
+0

Ooh, wait, nvm ... 매개 변수 타입은'Any'로 추론 될 것이라고 나는 생각한다. 기본 인수에 대해서도 동일합니다. 그것은'템플릿 C (Something )'에 대해서는 실패합니다. – Xeo

+0

나는 그것이 왜 실패할지 알지 못한다. T는 단순히 Any 유형이됩니다. –

+0

@Johannes : 예, 위의 새로운 설명을 참조하십시오. – Xeo

관련 문제