gpt4 book ai didi

C++1z - 如果在模板展开期间出现条件,则抛出编译错误

转载 作者:行者123 更新时间:2023-11-28 05:56:17 33 4
gpt4 key购买 nike

我正在编写一个模板,该模板定义了在类型参数包中提供给它的类型,其位置与传递给模板的数字相同。这是我写的:

template<size_t I, typename T, typename... Ts> 
struct get_type {
typedef typename std::conditional<I == 0, T, typename get_type<I-1, Ts...>::type>::type type;
};

template<size_t I, typename T>
struct get_type<I, T> {
// This works only if compiler stops unfolding the template when I == 0
static_assert(I == 0, "get_type - index out of bounds");
typedef T type;
};

这种方法的问题,如果我们这样写代码:

static_assert(std::is_same<double, get_type<1,int,double,float>::type>::value, "I wanted double!");

编译器仍然将模板“展开”到最后(即使到那时它应该知道类型,也就是 I 等于 0 的确切时间),并且在end I 溢出,不再等于 0,这意味着 static_assert 抛出错误,即索引 I 越界。但我仍然想在编译时以某种方式抛出一个错误,如果 I 真的越界了。有什么办法吗?

最佳答案

编译器必须展开模板,否则它不知道type 的类型是什么。

如果索引超出范围,

std::tuple_element_t 已经给出了一个(相当冗长的)错误。

template<size_t I, typename... Ts>
using get_type_t = std::tuple_element_t<I, std::tuple<Ts...>>;

通过将其与显式边界检查结合使用,可以生成更直观的错误消息:

template<size_t I, typename... Ts>
struct get_type {
using L=std::tuple<Ts...>;
static_assert(I < 0 || I >= std::tuple_size<L>(), "out of bounds");
using type = std::tuple_element_t<I, L>;
};

template<size_t I, typename... Ts>
using get_type_t = typename get_type<I, Ts...>::type;

这是一个没有 std::tuple 开销的例子(改编自 boostcon):

struct empty{};

template<class T>
struct tag_t:empty{};

template<class T>
tag_t<T> tag{};

template <typename ignore>
struct lookup;

template <std::size_t... ignore>
struct lookup<std::index_sequence<ignore...>> {
template <typename nth>
static nth
apply(decltype(ignore, empty())..., tag_t<nth>, ...);
};

template<std::size_t I, class... Ts>
using get_type = decltype(
lookup<std::make_index_sequence<I>>::apply(tag<Ts>...)
);

// Test
static_assert(std::is_same<get_type<1, int, float, int>, float>(), "");
static_assert(std::is_same<get_type<0, int, float, int>, int>(), "");

关于C++1z - 如果在模板展开期间出现条件,则抛出编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34106933/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com