除了专业外,使用默认特征

Using default Traits apart from the specializations

本文关键字:默认 特征      更新时间:2023-10-16

我要做的是创建一个具有默认逻辑的通用性状类,然后写代码以专门为每种特定情况而使用,只有与通用情况不同的事物。我的目标是删除代码重复并避免编写不必要的代码。

我给你一个例子:

int genericFunction(); // defined somewhere else
int specialFunction(); // defined somewhere else
template<int id>
struct IdTraits
  {
  using MyType = int;
  using AnotherType = double;
  static constexpr auto&& f = genericFunction;
  };
template<>
struct IdTraits<1>
  {
  // Using MyType and AnotherType of IdTraits generic case [how?]
  static constexpr auto&& f = specialFunction;
  };
template<>
struct IdTraits<2>
  {
  // Using MyType and f of IdTraits generic case [how?]
  using AnotherType = char;
  };
template<int id, class Traits = IdTraits<id>>
struct General
  {
  void foo(int arg)
    {
    Traits::MyType myType;
    Traits::AnotherType anotherType;
    Traits::f(arg);
    // Do stuff with myType and anotherType
    }
  };

您认为从理论上可以做这样的事情?

您可以使用第二个特征,而可以完成此工作。其目的是检查当前IdTrait<id>中的每个元素的存在,并设置默认类型/函数(如果不是(。

使用两种类型的当前实验检测,以及该功能的成员getF

template<int id>
struct MyIdTraits {
    template <typename T> using MyType_t = typename T::MyType;
    using MyType = std::experimental::detected_or_t<int, MyType_t, IdTraits<id>>;
    template <typename T> using AnotherType_t = typename T::AnotherType;
    using AnotherType = std::experimental::detected_or_t<double, AnotherType_t, IdTraits<id>>;
    template <typename T, typename = decltype(T::f)>
    static constexpr auto getF(int) { return T::f; }
    template <typename T>
    static constexpr auto getF(unsigned) { return genericFunction; }
    static constexpr auto&& f = getF<IdTraits<id>>(42);
};

然后用这个特征代替您的特征:

template<int id, class Traits = MyIdTraits<id>>
struct General { ... };

demo

是。将您的通用案例放在基类中:

namespace details
{
struct IdTraits_generic
{
    using MyType = int;
    using AnotherType = double;
    static constexpr auto&& f = genericFunction;
};
}
template<int id> struct IdTraits : details::IdTraits_generic
{
};
template<> struct IdTraits<1> : details::IdTraits_generic
{ 
  static constexpr auto&& f = specialFunction;
};
template<> struct IdTraits<2> : details::IdTraits_generic
{
  using AnotherType = char;
};