C++ 变量模板解包中达到终止功能时出现异常
因此,我正在使用模板&constexpr,特别是可变模板,我制作了以下函数:C++ 变量模板解包中达到终止功能时出现异常,c++,c++11,variadic-templates,constexpr,C++,C++11,Variadic Templates,Constexpr,因此,我正在使用模板&constexpr,特别是可变模板,我制作了以下函数: template <typename T> constexpr T get_argument(size_t index) { return T(); }; template <typename T, T arg, T... args> constexpr T get_argument(size_t index) { return index ? get_argument<T,ar
template <typename T>
constexpr T get_argument(size_t index)
{
return T();
};
template <typename T, T arg, T... args>
constexpr T get_argument(size_t index)
{
return index ? get_argument<T,args...>(index-1) : arg;
}
模板
constexpr T get_参数(大小索引)
{
返回T();
};
模板
constexpr T get_参数(大小索引)
{
返回索引?get_参数(索引-1):arg;
}
此处的终止函数当前是一个伪占位符。所以这个函数可以工作,但是如果超出范围,返回一个0,我希望它做的是崩溃…但是它需要两种模式的失败。get_参数可以在编译时调用,在编译时我希望索引超出范围,从而导致编译器错误。或者它可以在运行时调用,我希望它抛出一个运行时错误
我也有以下选择:
template <typename T>
constexpr T get_argument(size_t index)
{
return false ? T() : throw std::out_of_range("Index out of argument range");
}
template <typename T, T arg, T... args>
constexpr T get_argument(size_t index)
{
return index ?
(count_args<T,args...>() ?
get_argument<T,args...>(index-1) :
throw std::out_of_range("Index out of argument range")) :
arg;
}
模板
constexpr T get_参数(大小索引)
{
返回false?T():抛出std::超出参数范围(“索引超出参数范围”);
}
模板
constexpr T get_参数(大小索引)
{
回报指数?
(count_args()?
get_参数(索引-1):
抛出std::超出参数范围(“索引超出参数范围”):
精氨酸;
}
但是1)我不喜欢语法(总是假条件,加上模糊地检查两次以使输出有意义),2)错误很混乱:
test.hpp:32:69: error: expression '<throw-expression>' is not a constant-expression
throw std::out_of_range("Index out of argument range")) :
test.hpp:32:69:错误:表达式“”不是常量表达式
抛出std::超出参数范围(“索引超出参数范围”):
有人有更好的方法吗?以下内容可能会有所帮助(只有一项检查):
模板
constexpr std::数组getArray()
{
返回{Ts..};
}
模板
constexpr T get_参数(大小索引)
{
返回索引
C++14可能会有所帮助,可能会有几个语句,如:
- 局部变量(不需要此
)常量转换
(除了可能的assert
)throw
std::选项
。。。我想你可以自己包装它(用一个布尔值和默认值T
创建你自己的简单选项
)。有趣的解决方案…为什么需要const_cast?临时数组不是const,而操作符[]
只是const对象的constepr。啊,这很有意义(I+1,因为是的)。下一个问题:如果在运行时调用此函数,我的方法可以递归内联(如果编译器支持),这(可能,如果编译器有魔力)可以减少为常量值返回…此修复程序是否必须为std::数组进行堆分配?(我可能只需要检查程序集就可以得到这个答案,但如果你头脑清楚这一点,那就太酷了)(如果T没有默认构造函数,这也解决了问题)array::operator[]
在C++11中不是constexpr
。令人惊讶的是,代码实际上更简单。
template <typename T, T ... Ts>
constexpr std::array<T, sizeof...(Ts)> getArray()
{
return {{Ts...}};
}
template <typename T, T ... Ts>
constexpr T get_argument(size_t index)
{
return index < sizeof...(Ts) ?
const_cast<const std::array<T, sizeof...(Ts)>&&>(getArray<T, Ts...>())[index] :
throw std::out_of_range("Index out of argument range");;
}