对任意数量的可变参数应用函数
Applying a function over an arbitrary number of variadic arguments
这是 的后续问题。我正在构建一个具有基本矢量数学功能的数组 class。我想定义一个函数,让用户将任意函数映射到整个数组。我已经可以为预定义的二进制函数执行此操作(例如,operator+=
用于就地添加),但我正在努力了解如何对任意数量的输入执行此操作。
template<typename T, size_t ... Ns>
class Array
{
public:
Array() { /* allocate memory of size product(Ns) * sizeof(T) */ }
~Array() { /* deallocate memory */ }
inline Array<T, Ns...>& operator+=(const Array<T, Ns...> &rhs)
{
// simple case: predefined operation on exactly two Arrays
T *p1 = data, *p2 = rhs.data;
while (p1 != data + size) { *p1 += *p2; p1++; p2++; }
return *this;
}
template<class ... Args>
inline const Array<T, Ns...> map(T (*fn)(arg_type<Args>...), Args ... args)
{
// difficult case: arbitrary operations on a variable number of Arrays
}
private:
T *data;
size_t size;
}
// example usage
double f(double a, double b) { return a + b; }
Array<double,2> x, y, z;
x.map(f, y, z);
我想要这样的东西来遍历 y
和 z
中的所有元素,对它们应用 f
,并将它们存储在 x
中。我想我可以在我的 operator+=
函数上对其进行建模,但我还没有找到可以让我做任何类似事情(并编译)的参数包扩展。
这样写:
template<class T, class Array2>
using Array_Size_Copy = // expression that creates a Array<T,???>, where ??? is the Ns... of Array2 above
然后
template<class F, class A0, class...Arrays>
auto array_apply( F&& f, A0&& a0, Arrays&&...arrays ) {
using R = decay_t<decltype( f(std::declval<A0>().data.front(), std::declval<Arrays>().data.front()...) )>;
Array_Size_Copy<R, std::decay_t<A0>> retval;
for (int i = 0; i < a0.size(); ++i) {
retval.data[i] = f( std::forward<A0>(a0).data[i], std::forward<Arrays>(arrays).data[i]... );
}
return retval;
}
添加一些断言(理想情况下是静态断言)所有内容大小相同。
以上功能可能需要加好友。这意味着您可能必须设置 return 值而不是使用 auto
,但这只是将体操类型移动到声明中。
这是 operator+=
用于就地添加),但我正在努力了解如何对任意数量的输入执行此操作。
template<typename T, size_t ... Ns>
class Array
{
public:
Array() { /* allocate memory of size product(Ns) * sizeof(T) */ }
~Array() { /* deallocate memory */ }
inline Array<T, Ns...>& operator+=(const Array<T, Ns...> &rhs)
{
// simple case: predefined operation on exactly two Arrays
T *p1 = data, *p2 = rhs.data;
while (p1 != data + size) { *p1 += *p2; p1++; p2++; }
return *this;
}
template<class ... Args>
inline const Array<T, Ns...> map(T (*fn)(arg_type<Args>...), Args ... args)
{
// difficult case: arbitrary operations on a variable number of Arrays
}
private:
T *data;
size_t size;
}
// example usage
double f(double a, double b) { return a + b; }
Array<double,2> x, y, z;
x.map(f, y, z);
我想要这样的东西来遍历 y
和 z
中的所有元素,对它们应用 f
,并将它们存储在 x
中。我想我可以在我的 operator+=
函数上对其进行建模,但我还没有找到可以让我做任何类似事情(并编译)的参数包扩展。
这样写:
template<class T, class Array2>
using Array_Size_Copy = // expression that creates a Array<T,???>, where ??? is the Ns... of Array2 above
然后
template<class F, class A0, class...Arrays>
auto array_apply( F&& f, A0&& a0, Arrays&&...arrays ) {
using R = decay_t<decltype( f(std::declval<A0>().data.front(), std::declval<Arrays>().data.front()...) )>;
Array_Size_Copy<R, std::decay_t<A0>> retval;
for (int i = 0; i < a0.size(); ++i) {
retval.data[i] = f( std::forward<A0>(a0).data[i], std::forward<Arrays>(arrays).data[i]... );
}
return retval;
}
添加一些断言(理想情况下是静态断言)所有内容大小相同。
以上功能可能需要加好友。这意味着您可能必须设置 return 值而不是使用 auto
,但这只是将体操类型移动到声明中。