gpt4 book ai didi

c++ - 当模板参数无效时如何抛出异常?

转载 作者:搜寻专家 更新时间:2023-10-31 00:39:19 28 4
gpt4 key购买 nike

我有这段代码,我正在尝试使用 std::get 获得对元组的编译时访问权限。当用户输入一个超出元组范围的数字时,我想抛出一个异常。不幸的是,我无法让它工作,所以我让代码返回数组中的第一个元素(如果它超出范围)。

#include <tuple>

template <class... T>
struct input
{
std::tuple<T...> var;
input(T&&... t) : var(std::forward<T>(t)...) {}

template <
std::size_t N,
bool in_range = 0 <= N && N < std::tuple_size<decltype(var)>::value
>
auto get()
-> typename std::tuple_element<in_range ? N : 0, decltype(var)>::type&&
{
return std::move( std::get<in_range ? N : 0>(var) );
}
};

template <class... Args>
void f(Args&&... args)
{
auto arguments = input<Args...>(std::forward<Args>(args)...);

arguments.template get<9>(); // returns 2 but I'd rather throw an exception
}

int main()
{
f(2, 4, 6, 8);
}

我怎样才能抛出异常或至少使用 static_assert 技巧来让它工作?

最佳答案

异常用于报告运行时错误,而您在这里处理的是编译时编程问题。

如果您介意编译器会在您尝试实例化 tuple_element<> 时出现不太明显的错误使用越界索引,您可以使用 SFINAE 来防止您的函数在重载解析期间完全实例化:

template <class... T>
struct input
{
std::tuple<T...> var;
input(T&&... t) : var(std::forward<T>(t)...) {}

template<std::size_t N,
typename std::enable_if<(N < std::tuple_size<decltype(var)>::value)>::
type* = nullptr>
auto get() -> typename std::tuple_element<N, decltype(var)>::type&&
{
return std::move( std::get<N>(var) );
}
};

如果你想添加一个更清晰的static_assert() ,您可以通过添加仅在 N 时才选取的重载来实现出界:

    template<std::size_t N,
typename std::enable_if<(N >= std::tuple_size<decltype(var)>::value)>::
type* = nullptr>
void get()
{
static_assert(N < std::tuple_size<decltype(var)>::value, "OOB");
}

这是一个live example .

关于c++ - 当模板参数无效时如何抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366248/

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