2015-12-15 96 views
5

假设我想使用std::conditional来确定类型,如果类型是vector<...>,则返回将是vector<...>::size_type,否则将是int。 (只是一个例子)。是否可以构建lazy_conditional元函数

使用std::conditional一个天真的方式:

template<class V> struct is_vector : std::false_type{}; 
template<class T> struct is_vector<std::vector<T>> : std::true_type{}; 

template<class C> 
using my_size_type = typename std::conditional< 
    not is_vector<C>::value, 
    int, 
    C::size_type // note that this line only makes sense when condition is false 
>::type; 

但是这种失败,因为如果C是说doubledouble::size_type会给出一个错误,即使是第二个错误选项的评估。

所以,我想知道是否有一种lazy_conditional其中的虚假(或第二个虚假)声明不评估。

我在这里找到了一些东西:https://stackoverflow.com/a/5317659/225186但我不知道如何使用它我的例子。


注意,我知道如何得到相同的结果,而无需使用std::conditional

template<class V> struct my_size_type{typedef int type;}; 
template<class T> struct my_size_type<std::vector<T>>{typedef std::vector<T>::size_type type;}; 

的问题是,如果有一个lazy_conditional,不知怎的,封装在std::conditional是短路。


一些审判的错误,我设法用意念在https://stackoverflow.com/a/5317659/225186,并获得该遵循之后。这也使我认为不可能写std::lazy_conditional,因为C::size_type根本不能出现在任何表达式中,所以需要两步表达式。

template<class C, bool B> struct false_case{ 
    typedef void type; 
}; 
template<class C> struct false_case<C, false>{ 
    typedef typename C::size_type type; 
}; 

template<class C> 
using size_type = typename std::conditional< 
    not is_vector<C>::value, 
    int, 
    typename false_case<C, not is_vector<C>::value>::type 
>::type; 

我甚至无法将它压缩成一个宏,因为每种情况都不一样。

回答

4

您需要一个间接的级别。

template<class T> struct identity { using type = T; }; 

template<class C> 
struct size_type_of : identity<typename C::size_type> { }; 

template<class C> 
using size_type = typename std::conditional<not is_vector<C>::value, 
              identity<int>, 
              size_type_of<C>>::type::type; 

关键是耽误看C::size_type(通过实例size_type_of<C>),直到你知道它有一个。


如果你真的想要做的是“C::size_type如果它存在,否则int”,然后std::experimental::detected_or_t是你的朋友:

template<class C> 
using size_type_t = typename C::size_type; 

template<class C> 
using size_type_or_default = std::experimental::detected_or_t<int, size_type_t, C>; 
+0

好吧,我想它不能被封装成'lazy_conditional '。无论如何,这也表明免费元函数比成员(有std :: size_type_of :: type而不是依赖于T :: size_type)要好(如自由函数比泛型代码的成员函数更好)。 – alfC

+0

啊,这是我一遍又一遍发现的东西,最后它是我在这里做的一样:http://stackoverflow.com/questions/5839357/detect-operator-support-with-decltype-sfinae/18603716# 18603716 – alfC

+0

关于'detected_or_t'兼容性:http://stackoverflow.com/questions/36418570/what-c​​ompiler-option-library-do-i-need-to-use-detect-or-t-type-trait?noredirect= 1个#comment60486585_36418570 – alfC

相关问题