c++ - 是否可以构建一个惰性条件元函数

标签 c++ templates c++11 conditional short-circuiting

假设我想使用 std::conditional确定类型,如果类型是 vector<...>返回将是 vector<...>::size_type如果不是,它将是 int . (只是一个例子)。

一种天真的使用方式 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是说 double , double::size_type将给出一个错误,即使那是第二个 false 选项的评估。

所以,我想知道是否有一种 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;

我什至无法将其压缩成一个宏,因为每个案例都是不同的。

最佳答案

您需要一定程度的间接访问。

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 是你的 friend :

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>;

关于c++ - 是否可以构建一个惰性条件元函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34281017/

相关文章:

c++ - 优化 dijkstra 实现

Python Cheetah - 为模板指定名称/值对

c++ - std::map 中的 std::pair 作为 const 返回

c++ - 自动化 C++ 类的 pimpl'ing——有简单的方法吗?

c++ - 实现像 ios_base::Init 这样的初始化器的标准方法

c++ - 由于未知的模板定义,模板特化失败

c++ - 使用 Image.ptr<double>(0);在 OpenCV 中使用彩色图像

c++ - 使用蒙特卡罗方法多线程计算 pi 值

c++ - 指针究竟如何遍历字符串/数组?

c++ - 我如何检查模板是否编译出来?