将类似数组的对象作为模板值参数
Put array-like object as template value argument
我想实现
template<class ValueType,UnitTag x>
clsas Quantity;
与
这样的操作员template<UnitTag y>
Quantity<T,x+y> operator*(Quantity<T,y> b)
{return Quantity<T,x+y>(m_value*b.value());}
(也可以添加数量,但只有相同的数量)
必须完成 UnitTag
s的操作,以完成元素
x_0 + y_0 = z_0
x_1 + y_1 = z_1
x_2 + y_2 = z_2
x_3 + y_3 = z_3
...
最直接的方法是让UnitTag
成为一个constexpr数组。但这不能用作模板参数。作为解决方法,我可以使用大整数类型进行操作,并使用少量的位来表示每个维度。但是,这给出了尺寸数量或每个维度的功率的限制:例如,使用64位和16个维度,我只覆盖[l^( - 8),l^7]。这对于大多数应用程序应该是有益的,但是班级无法处理激进分子,因为这需要分数权力。
是否有任何方法可以在模板参数中传递超过64位信息?例如,是否可以在模板参数包上进行元素操作?元素操作是:
- 加法(用于乘法)
- 减法(用于分裂)
激进分子:
- division(这需要元素像理性数字一样行为。可以使用
constexpr word()
访问者实现为类)
我尝试根据
提出解决方案是否可以在模板参数包上进行元素操作?
不确定(我不知道您确切想对此值做什么),但是如果您将模板参数包包装在std::integer_sequence
(或std::index_sequence
,如果可以使用std::size_t
),则似乎可以对我。
不幸的是,std::integer_sequence
和std::index_sequence
是C 14个功能。但是,如果您需要在C 11中,那么实现类似的功能很容易。
以下是使用std::index_sequence
- 编辑 - 修改的示例添加减法/除法
#include <utility>
#include <type_traits>
template <typename, typename>
struct addVI;
template <std::size_t ... Is, std::size_t ... Js>
struct addVI<std::index_sequence<Is...>, std::index_sequence<Js...>>
{
static_assert(sizeof...(Is) == sizeof...(Js), "! add");
using type = std::index_sequence<(Is+Js)...>;
};
template <typename, typename>
struct subVI;
template <std::size_t ... Is, std::size_t ... Js>
struct subVI<std::index_sequence<Is...>, std::index_sequence<Js...>>
{
static_assert(sizeof...(Is) == sizeof...(Js), "! sub");
using type = std::index_sequence<(Is-Js)...>;
};
template <typename, typename>
struct foo;
template <typename T, std::size_t ... Is>
struct foo<T, std::index_sequence<Is...>>
{
template <std::size_t ... Js>
using Ks = typename addVI<std::index_sequence<Is...>,
std::index_sequence<Js...>>::type;
template <std::size_t ... Js>
using Ls = typename subVI<std::index_sequence<Is...>,
std::index_sequence<Js...>>::type;
template <std::size_t ... Js>
foo<T, Ks<Js...>> operator* (foo<T, std::index_sequence<Js...>> const & b)
{ return foo<T, Ks<Js...>>(); }
template <std::size_t ... Js>
foo<T, Ls<Js...>> operator/ (foo<T, std::index_sequence<Js...>> const & b)
{ return foo<T, Ls<Js...>>(); }
};
int main ()
{
foo<int, std::index_sequence<1, 2, 3>> f1;
foo<int, std::index_sequence<2, 3, 5>> f2;
static_assert(std::is_same<decltype(f1*f2),
foo<int, std::index_sequence<3, 5, 8>>>::value,
"!!");
static_assert(std::is_same<decltype(f2/f1),
foo<int, std::index_sequence<1, 1, 2>>>::value,
"!!!");
}
只需通过几个整数参数。
作为替代方案,请探讨亚伯拉罕和古尔图沃伊的" C 模板元编程"。他们将此想法称为"维度分析",并使用UnitTag
的类型列表。
typedef mpl::vector_c<int,0,1,0,0,0,0,0> length;
typedef mpl::vector_c<int,0,0,1,0,0,0,0> si_time;
...
typedef mpl::vector_c<int,0,1,-1,0,0,0,0> velocity;
...
标签的乘法运算符D1
和D2
制作类型列表
typename mpl::transform<D1,D2,mpl::plus<_1,_2> >::type
相关文章:
- 为什么默认复制函数在按值发送参数时不调用?
- 如何在另一个函数中使用返回值作为参数?
- 为什么 string_view::operator== 按值接受参数
- 在 c++ 中,如果我创建一个接受一个具有默认值的参数的构造函数 - 它会用作默认(空)构造函数吗?
- 在子类函数覆盖中省略具有默认值的参数
- C++区分函子和值模板参数
- 函数作为具有默认值的参数
- Lambda闭包左值可以作为右值参考参数传递
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- 向心Catmull-Rom样条曲线插值alpha参数
- 当我按值传递参数时对象被破坏时?
- 如何强制函数仅接受左值引用参数
- 用于赋值的参数化构造函数
- 为什么C++可变参数模板不接受 iostream 值作为参数?
- 移动 l 值参考参数是否是一种不好的做法?
- 为什么静态常量字符 * const 变量在为左值时可绑定到右值引用参数
- 具有默认值的参数的自动类型扣除
- 推导用户定义的值模板参数(C++2a、P0732R2)
- 将 r 值引用传递给 r 值引用参数时出错
- C++ 基构造函数左值到参数