是否可以为一组特定的不同类型编写一次代码? [英] Possible to write the code once for a specific set of different types?

查看:80
本文介绍了是否可以为一组特定的不同类型编写一次代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板类 TC ,其构造函数使用值依赖的参数,并且其类型为 Tn

I have a template class TC who's constructor takes parameters who's values are dependent on, as well as being of type Tn.

因此,我想创建一个辅助模板函数 htf ,该函数将调用与<$ c $相同的函数c> Tn 对象为一组类型为 X0 TC c $ c> Xn 。辅助函数仅从该集合中获取一个参数。是否有可能使用可变参数模板为一组类型编写一次函数,而不必为每种类型重复编写相同的函数?

So, I want to create a helper template function htf that will call the same functions of a Tn object to generate a TC for a set of types X0 to Xn. The helper function takes only one parameter from that set. Is it possible, perhaps with variadic templates, to write the function once for the set of types, instead of having to write the same function over and over again for each type?

现在,我可以只使用模板来允许所有类型,但是我不希望这样,因为稍后可能会为该特定类型编写具有相同名称的另一个函数,该函数不基于此 TC 。而且,IIRC我认为 SFINAE 使用成员函数,而不是 pure 函数。

Now, I could just use a template to allow all types, but I don't want that as there may be another function with the same name written for a specific type later that's not based on this TC. And, IIRC I think SFINAE works with member functions, not pure functions.

这只是我脑海中的一个想法此刻,这就是为什么这个问题很笼统的原因。但是,以下是我正在考虑的大致代码,以更具体,更笼统的方式进行了简化:

This is just an idea in my head at the moment, that's why the question is very general. However, here is roughly the code I'm thinking of, simplified, in an more concrete and in an over generalized fashion:

struct X0
{
  int value;
  int& fn() { return value; }
};

struct X1
{
  double value;
  double& fn() { return value; }
};

struct X2
{
  float value;
  float& fn() { return value; }
};

struct Y0 // don't accept this class in helper function
{
  int value;
  int& fn() { return value; }
};

template<typename T1, typename Tn>
class TC
{
  T1* m_pT1;
  Tn* m_pTn;
  TC(T1* pT1, Tn* pTn) : m_pT1(pT1), m_pTn(pTn) {}
  friend TC htf(Tn& tn);
public:
  ~TC() {}
};

// concrete functions:
TC<int,    X0> htf(C0& x) { return TC<int,    X0>(&x.fn(), &x); }
TC<double, X1> htf(C1& x) { return TC<double, X1>(&x.fn(), &x); }
TC<float,  X2> htf(C2& x) { return TC<float,  X2>(&x.fn(), &x); }

// or in an over generalized template function but it'll accept
// Y0 and others which I don't want:
template<typename X>
auto htf(X& x) -> TC<decltype(x.fn()), X>
{
  return TC<decltype(x.fn()), X>(&x.fn(), &x);
}

所以我想要的 htf 函数适用于 X0 X1 X2 的类,但不是 Y0 。但是,我不想让它干扰名为 htf 的任何其他函数,该函数的参数类型为 Y0 ,或与此有关的任何其他类型。

So the htf function that I want is to work for classes X0, X1, and X2, but not Y0. However, I don't want it to interfere with any other function called htf that takes a parameter of type Y0, or any other type for that matter.

是否有可能做到这一点,以使接受类的集合也可以包括采用指定(或未指定)数量的参数?

Is it possible to make it so that the collection of accepted classes can also include template classes taking an specified (or unspecified) number of parameters?

推荐答案

编写仅在特征为true时启用的函数,然后进行专门化

Write a function that is only enabled when a trait is true, then specialize it for all the desired types.

template<typename T>
struct enable_htf : std::false_type { };

template<>
struct enable_htf<X0> : std::true_type { };

template<>
struct enable_htf<X1> : std::true_type { };

// etc.

template<typename T, bool enable = enable_htf<T>::value>
struct htf_helper { };

template<typename T>
struct htf_helper<T, true>
{
  using type = TC<decltype(std::declval<T&>().fn()), T>;
};

template<typename X>
typename htf_helper<X>::type
htf(X& x)
{
  return { &x.fn(), &x };
}

但是您似乎想要这样的东西:

But it seems you want something like this instead:

template<typename Needle, typename... Haystack>
struct is_one_of;

template<typename Needle, typename Head, typename... Tail>
struct is_one_of<Needle, Head, Tail...>
: conditional<is_same<Needle, Head>::value, true_type,
              is_one_of<Needle, Tail...>>::type
{ };

template<typename Needle>
struct is_one_of<Needle> : false_type
{ };

template<typename X,
         typename Requires = typename enable_if<is_one_of<X, X0, X1, X2>::value>::type>
auto
htf(X& x) -> TC<decltype(x.fn()), X>
{
  return { &x.fn(), &x };
}

但就我个人而言,即使 is_one_of 可在其他地方重用。

But personally I don't consider that clearer, even if is_one_of is reusable elsewhere.

这篇关于是否可以为一组特定的不同类型编写一次代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆