没有子类型的C ++模板

时间:2016-04-05 21:20:52

标签: c++ templates

我有类似

的东西
template<typename T, typename U = SOMETHING<T>> class A;

template<typename T> using B = A<T, SOMETHING_ELSE<T>>;

如何确定在函数实例化中是否使用SOMETHINGSOMETHING_ELSE,例如:

class A: {
template<typename V>
create_new(V v); // return an A only depending on SOMETHING or SOMETHING_ELSE,
  // e.G: if A is instantiated with T, SOMETHING<T> the return shall be A<V, SOMETHING<V> >,
  // but if it is SOMETHING_ELSE, the return shall be of type A<V, SOMETHING_ELSE<V> >
}

我知道可以使用模板专业化,但是有更好的&#34;更美丽&#34;在添加更多SOMETHINGS时,不必编写大量新的spezialisations?

真实代码:

template<typename Type = long, typename Canceling_Type<Type> = fract::canceled<Type>>
class fraction; // there are different canceling types

所需的功能是

template<typename Other_Type, typename Other_Cancel_Type>
fraction<decltype(Type() + Other_Type()), WHAT_HERE> &operator+(const fraction<Other_Type,Other_Cancel_Type> &

cancel_types只包含一个取消分数的静态函数(或者没有取消)(未取消与该示例类似)

template<typename Type>
class meng::math::fract::canceled {
public:
  typedef fraction<Type,canceled<Type>> cancel_type;
  static cancel_type &cancel(cancel_type& to_cancel);
};

我的想法是用f创建一个分数,这样就不会丢失精度(例如int和long类型会产生一小部分长), 但有一种取消由两个部分决定(例如 取消了收益率,混合收益率没有取消,例如。只改变了setter函数的行为,但它们是相同的数学概念,因此可以一起计算)

(英语不是我的第一语言,因此我希望取消分数意味着使用尽可能小的分子和分子)

1 个答案:

答案 0 :(得分:0)

如果我得到你的意图,你可以专注于某种特质。

namespace detail
{
  template<class T, class U, class CancelT, class CancelU>
  struct cancelor
  {
    using type = fract::uncanceled<std::common_type_t<T, U>>;
  };
  template<class T, class U>
  struct cancelor<T, U, fract::canceled<T>, fract::canceled<U>>
  {
    using type = fract::canceled<std::common_type_t<T, U>>;
  };
  template<class T, class U, class CancelT, class CancelU>
  using cancel_t = typename cancelor<T, U, CancelT, CancelU>::type;
}

template<class T, class CancelT = fract::canceled<T>>
struct X
{
  template<class U, class CancelU>
  X<std::common_type_t<T, U>, detail::cancel_t<T, U, CancelT, CancelU>> 
    operator+(X<U, CancelU> const & v) 
  { 
    using V = std::common_type_t<T, U>;
    using C = detail::cancel_t<T, U, CancelT, CancelU>;
    auto ret = X<V, C>{/*...*/};
    // do stuff with ret
    return ret;
  }
};

然后添加它们:

X<int, fract::canceled<int>> ci;
X<int, fract::uncanceled<int>> ui;
X<long, fract::canceled<long>> cl;
X<long, fract::uncanceled<long>> ul;

auto c = ci + cl;
auto u = ui + ul;
auto cu = ci + ul;
auto uc = ui + cl;

std::cout << type_name<decltype(c)>() << "\n";
std::cout << type_name<decltype(u)>() << "\n";
std::cout << type_name<decltype(cu)>() << "\n";
std::cout << type_name<decltype(uc)>() << "\n";

输出为:

struct X<long,struct fract::canceled<long>>
struct X<long,struct fract::uncanceled<long>>
struct X<long,struct fract::uncanceled<long>>
struct X<long,struct fract::uncanceled<long>>