2012-12-19 2 views
6

나는 가변적 인 템플릿 클래스와 함께 SFINAE를 사용하는 좋은 해결책을 찾지 못하는 것 같다.가변 템플릿 클래스가있는 SFAAE?

template<typename... Args> 
class NoRef 
{ 
    //if any of Args... is a reference, this class will break 
    //for example: 
    std::tuple<std::unique_ptr<Args>...> uptrs; 
}; 

편리하게 인수 팩이 참조가 포함 된 경우 확인하는 클래스 : 나는 어떻게 사용합니까

template<typename T, typename... Other> 
struct RefCheck 
{ 
    static const bool value = std::is_reference<T>::value || RefCheck<Other...>::value; 
}; 
template<typename T> 
struct RefCheck<T> 
{ 
    static const bool value = std::is_reference<T>::value; 
}; 

의 내가 참조를 좋아하지 않는 가변 인자 템플릿 객체가 있다고 가정 해 봅시다 arg 팩에 참조가있는 경우 NoRef를 전문화하려면?

답변

9

이 SFINAE를 사용하지만 기본적으로 당신이하려는 것을 수행하지 않습니다

template<bool Ref, typename... Args> 
class NoRef_; 

template<typename... Args> 
class NoRef_<false, Args...> 
{ 
    std::tuple<std::unique_ptr<Args>...> uptrs; 
}; 
template<typename... Args> 
class NoRef_<true, Args...> 
{ 
    // contains reference 
}; 

template<typename... Args> 
using NoRef = NoRef_<RefCheck<Args...>::value, Args...>; 

// alternative from Nawaz 

template<typename... Args> struct NoRef : NoRef_<RefCheck<Args...>::value, Args...> {} 
+0

+1. 하지만 생각해 보면'template 구조체 NoRef : NoRef_ :: value, Args ...> {};'더 좋을 것입니다. 이제 'NoRef'는 템플릿 템플릿 매개 변수가 아닌 다른 클래스 템플릿입니다 (예 : 부울 값). – Nawaz

+0

MSVC에서 아직 템플릿 별칭을 지정할 수는 없지만이 솔루션이 마음에 듭니다. 그러나 Nawaz는 그 해결책을 제공했습니다. –

6

템플릿 팩이 다루기 힘들 기 때문에 그대로 둘 수는 없습니다. 그러나 팩을 팩할 수 있습니다.

// Used to transport a full pack in a single template argument 
template <typename... Args> struct Pack {}; 

우리는 레퍼런스 체크 적응 :

template <typename T, typename... Other> 
struct RefCheck 
{ 
    static const bool value = std::is_reference<T>::value 
          || RefCheck<Other...>::value; 
}; 

template <typename T> 
struct RefCheck<T> 
{ 
    static const bool value = std::is_reference<T>::value; 
}; 

template <typename... Args> 
struct RefCheck<Pack<Args...>>: RefCheck<Args...> {}; 

을 그리고 지금 우리가 사용할 수있는 Pack :

template <typename P, bool = RefCheck<P>::value> class NoRef; 

template <typename... Args> 
class NoRef<Pack<Args...>, false> { 
    // no reference in Args... here 
}; 
관련 문제