如果您正在跟踪我的问题历史,我将更新一个多维分析库,以摆脱宏的噩梦,学习C++11、各种模板以及元编程和函数式编程范例。对于我的生命来说,这些东西仍然是神奇的。
无论如何,我有定义物理单位的指数常数元组。
template<int... I>
using make_dimension = std::tuple<std::ratio<I>...>;
using scalar_dimension = make_dimension<0, 0, 0, 0, 0, 0, 0>;
using length_dimension = make_dimension<1, 0, 0, 0, 0, 0, 0>;
using time_dimension = make_dimension<0, 0, 1, 0, 0, 0, 0>;这是为SI单元建模的库的一部分。您只能与单位相乘,还可以添加类似的单位和标量。这些库很好,因为如果不适当地混合单元,它们会导致编译时错误。有超过400个单位,其中大部分是用其他单位来定义的。当乘积单位,指数被加,当除法单位时,指数被减去。因此,为了定义速度,我希望有一种表达方式:
using velocity_dimension = divide_dimensions<length_dimension, time_dimension>;这在功能上应该等同于写作:
using velocity_dimension = make_dimension<1, 0, -1, 0, 0, 0, 0>;我一直在谷歌搜索,但我只是不知道如何使用术语来获得一些点击率。我发现最近的是一个for_each,它在运行时将函数应用于元组的元素.这让我有点抓狂,所以我不知道如何将它转化为对元素的编译时迭代。刚才有人向我解释了上面的“make_dimension”,这让我大吃一惊,但我恢复了过来。我有点想要一份讲义,所以有人有什么好的资源来学习这些东西吗?我很难相信我是唯一一个对此有兴趣的人。
发布于 2014-10-09 04:32:30
@dyp在注释中的解决方案使用递归实例化模板。虽然这是用于各种模板的最常用技术之一,但在这种情况下,递归可能会导致过度,因为整个转换集可以在单个包展开中执行,该扩展同时扩展两个参数包:
template<template<class, class> class, class, class>
struct tuple_transform; // undefined
template<template<class, class> class Transform, class...Ts, class...Vs>
struct tuple_transform<Transform, std::tuple<Ts...>, std::tuple<Vs...>> {
using type = std::tuple<Transform<Ts, Vs>...>;
};
template<class T, class U>
using divide_dimensions = typename tuple_transform<std::ratio_subtract, T, U>::type;请注意,上面的假设是Transform<T, U>是所需结果类型的别名。这与ratio_add等的行为相匹配--它们是生成的std::ratio的别名模板,因此typename ratio_add<...>::type是不必要的。
演示。
发布于 2014-10-10 08:27:30
虽然T.C.s的答案是正确的,但您可以简单地使用序列 (它是C++ 14,但可以简单地实现),而不是比率和元组,在我看来,它们并不完全适合,并且使用一个常数函子进行操作。现在,您的代码应该如下所示(我没有尝试编译):
template<int... I>
using make_dimension = std::integer_sequence<int, I...>;
template<class Functor, class Dim1, class Dim2>
struct transfrom;
template<class Functor, int... Dims1, int... Dims2>
struct transform<
Functor,
std::integer_sequence<int, Dims1...>,
std::integer_sequence<int, Dims2...>
> {
static_assert(sizeof...(Dims1)==sizeof...(Dims2), "wrong dimensions");
static constexpr Functor f;
using type=std::integer_sequence<int, f(Dims1,Dims2)...>;
};
struct add {
constexpr int operator()(int l, int r) const { return l+r; }
};
struct sub {
constexpr int operator()(int l, int r) const { return l-r; }
};
template<class T, class U>
using divide_dimensions = typename transform<sub, T, U>::type;发布于 2014-10-09 00:43:06
我没有足够的信息,但是看起来(1,0,-2,0,0,0,0,0)是加速所需要的。1表示米,-2表示秒平方,就像数学中的负指数一样。
https://stackoverflow.com/questions/26268472
复制相似问题