Constexpr函数用于向数组中添加整数
constexpr function to add an integer to an array
我正试图实现一个constexpr函数"add42",这将允许我做:
constexpr array<int,5> arr = {1,2,3,4,5};
constexpr array<int,5> arr2 = add42(0,arr); //I want arr2=={43,2,3,4,5}
也就是说,静态地(使用constexpr)将给定索引处的整数添加到数组中。因为我的数组arr是不可变的,我必须从arr和索引中创建一个新的数组。这就是为什么我编写了这个函数:
template<int DIM, typename... ARGS> auto constexpr
add42(int index, array<int,DIM> intergerArray, ARGS... unpackedIntegers) -> array<int,DIM> {
return
( sizeof...(ARGS)==DIM ) ?
array<int,DIM>( {{unpackedIntegers...}} ) :
( (sizeof...(ARGS)-1)==index ) ?
add42(index, intergerArray, unpackedIntegers..., intergerArray[sizeof...(ARGS)-1]+42 ) :
add42(index, intergerArray, unpackedIntegers..., intergerArray[sizeof...(ARGS)-1] ) ;
}
也就是说,我的数组中的所有整数都从数组中递归解包,在右索引处添加42,并出现在ARGS列表的末尾。当此参数列表包含数组中的所有整数时,就可以将其重新打包到一个新数组中。
但是我得到这个错误(gcc 4.7.2)
error: no matching function for call to 'add42(int, const std::array<int, 5u>&)'|
note: candidate is:|
template<int DIM, class ... ARGS> constexpr std::array<int, DIM> add42(int, std::array<int, DIM>, ARGS ...)|
note: template argument deduction/substitution failed:|
note: mismatched types 'int' and '#'integer_cst' not supported by dump_type#<type error>'|
你能告诉我是什么问题以及如何纠正它吗?
这个问题似乎类似于c++ 11:数组的编译时间计算,但不是(至少,我无法弄清楚如何直接使用它):在这里,我想从一个已经存在的一个创建一个新的数组,而不是从一个已知的整数序列。
编辑
现在我得到了无限实例化,即使没有调用递归。下面是一个简单的例子:
template<size_t DIM, typename... ARGS> auto constexpr
add42(int index, array<int,DIM> integerArray, ARGS... unpackedIntegers) -> array<int,DIM> {
return
( true ) ?
array<int,DIM>( {{unpackedIntegers...}} ) :
add42(index, integerArray, unpackedIntegers..., integerArray[(sizeof...(ARGS)-1)] ) ;
}
为什么我的编译器试图编译最后一个函数调用?
编辑2
显然,为了不混淆编译器,我必须提供两个函数:
template<size_t DIM, class... ARGS> constexpr auto
add42(int index, array<int,DIM> integerArray, ARGS... unpackedIntegers) -> typename enable_if<sizeof...(ARGS)==DIM ,array<int,DIM>>::type
{
return array<int,DIM>( {{unpackedIntegers...}} );
}
template<size_t DIM, class... ARGS> constexpr auto
add42(int index, array<int,DIM> integerArray, ARGS... unpackedIntegers) -> typename enable_if<sizeof...(ARGS)!=DIM ,array<int,DIM>>::type
{
return
( sizeof...(ARGS) == index ) ?
add42(index, integerArray, unpackedIntegers..., integerArray[sizeof...(ARGS)]+42) :
add42(index, integerArray, unpackedIntegers..., integerArray[sizeof...(ARGS)]) ;
}
但是它仍然不工作:
recursively required from [[name of the second function]]
显然,可变函数不能"递归地"调用它的重载之一。我说的对吗?
你应该使用
template<size_t DIM, typename... ARGS> auto constexpr
add42(int index, array<int,DIM> intergerArray, ARGS... unpackedIntegers)
因为数组的第二个参数的类型是size_t
,而不是int
。
不幸的是,std::array::operator[]
是不是 constexpr
。
编译器选项:只是普通的-std=c++11
gcc <= 4.6: -std=c++0x
并将using
指令替换为typedef
#include <cstddef>
//#include <array>
#include <type_traits>
#include <iostream>
template < typename T, std::size_t dim >
struct c_array
{
T arr[dim];
constexpr T operator[](std::size_t index)
{ return arr[index]; }
T const* begin() const
{ return arr; }
T const* end() const
{ return arr+dim; }
};
// I like the overloaded version better (instead of enable_if) :)
template < typename T, std::size_t dim, typename... TT >
constexpr c_array<T, dim>
add_to(T s, c_array<T, dim> in, std::size_t index, std::true_type, TT... pp)
{
return {{pp...}};
}
template < typename T, std::size_t dim, typename... TT >
constexpr c_array<T, dim>
add_to(T s, c_array<T, dim> in, std::size_t index, std::false_type, TT... pp)
{
using test = std::integral_constant<bool, (sizeof...(pp)+1 == dim)>;
return index == sizeof...(pp)
? add_to(s, in, index, test{}, pp..., in[sizeof...(pp)]+s)
: add_to(s, in, index, test{}, pp..., in[sizeof...(pp)] );
}
// unfortunately, I don't know how to avoid this additional overload :(
template < typename T, std::size_t dim>
constexpr c_array<T, dim>
add_to(T s, c_array<T, dim> in, std::size_t index)
{
return add_to(s, in, index, std::false_type{});
}
constexpr c_array<int,5> arr = {1,2,3,4,5};
constexpr c_array<int,5> arr2 = add_to(42, arr, 0); //I want arr2=={43,2,3,4,5}
int main()
{
for(auto const& e : arr2)
{
std::cout << e << ", ";
}
}
另一个版本,稍微有点别扭的用法语法:
// helper; construct a sequence of non-type template arguments
template < std::size_t... tt_i >
struct seq
{};
template < std::size_t t_n, std::size_t... tt_i >
struct gen_seq
: gen_seq < t_n-1, t_n-1, tt_i...>
{};
template < std::size_t... tt_i >
struct gen_seq < 0, tt_i... >
: seq < tt_i... >
{};
template < std::size_t index, typename T, std::size_t dim,
std::size_t... tt_bef, std::size_t... tt_aft >
constexpr c_array<T, dim>
add_to(T s, c_array<T, dim> in, seq<tt_bef...>, seq<tt_aft...>)
{
return {{ in[tt_bef]..., in[index]+s, in[tt_aft]... }};
}
template < std::size_t index, typename T, std::size_t dim >
constexpr c_array<T, dim>
add_to(T s, c_array<T, dim> in)
{
return add_to<index>(s, in, gen_seq<index>{}, gen_seq<dim-index-1>{});
}
constexpr c_array<int,5> arr = {1,2,3,4,5};
constexpr c_array<int,5> arr2 = add_to<0>(42, arr);
相关文章:
- 添加存储在向量中的大整数的函数出现问题
- 当我们从/tp地址中添加/减去一个整数时会发生什么
- 如何在 sqlite3 中的表中添加整数列表
- 使用指针将 ASCII 值添加到整数
- 我正在尝试制作一个程序,在添加 n 天(整数)后告诉一个人什么是一天(例如星期一等)
- C++向数组添加元素并调整数组大小
- 斯塔克,堆栈,也可以在底部和顶部添加整数
- 如何编写模板函数来添加整数但连接字符串和字符类型?
- 如何在字符串中添加整数
- 如何在 c++ 中使用输入重定向添加整数
- 如何在同一向量中添加整数和字符串
- 为什么在添加整数时,STD :: String返回字符串的尾巴
- 每行添加整数并将其存储在数组中
- 在C++中添加整数的输出
- 为什么可以向字符串字面值添加整数?
- Constexpr函数用于向数组中添加整数
- for循环添加整数
- 为什么使用std::next而不是向指针添加整数
- 添加整数字符串
- 在向量中添加整数