c++ - 这个 SFINAE 模式有名字吗?

标签 c++ templates design-patterns sfinae

在“太阳底下没有新鲜事”的规则下运作,我怀疑我是第一个想出这个把戏的人。我想我最终会偶然发现一些在线记录它的东西,但我还没有,所以我想我会问。

它的目的是在不使用派生类的情况下有选择地启用某些相关的功能。

这个图案有名字吗?有没有人有任何关于这种模式或类似运作模式的有用信息?

template<typename T, size_t N>
class Point {
public:
  template<size_t P, typename T2=void>
  using Enable2D = typename std::enable_if<P == 2 && N == P, T2>::type;
  template<size_t P, typename T2=void>
  using Enable3D = typename std::enable_if<P == 3 && N == P, T2>::type;
  template<size_t P, typename T2=void>
  using Enable4D = typename std::enable_if<P == 4 && N == P, T2>::type;
  template<size_t P, typename T2=void>
  using Enable2DOrHigher = typename std::enable_if<P >= 2 && N == P, T2>::type;
  template<size_t P, typename T2=void>
  using Enable3DOrHigher = typename std::enable_if<P >= 3 && N == P, T2>::type;
  template<size_t P, typename T2=void>
  using Enable4DOrHigher = typename std::enable_if<P >= 4 && N == P, T2>::type;

  //Example use cases
  template<size_t P=N>
  static Enable2D<P, Point> withAngle(T angle, T magnitude = 1);
  template<size_t P=N>
  static Enable3D<P, Point> fromAngles(T psi, T theta, T magnitude = 1);

  template<size_t P=N>
  Enable2DOrHigher<P, T> const& x() const;
  template<size_t P=N>
  Enable2DOrHigher<P, T> const& y() const;
  template<size_t P=N>
  Enable2DOrHigher<P> setX(T const& t);
  template<size_t P=N>
  Enable2DOrHigher<P> setY(T const& t);

  template<size_t P=N>
  Enable3DOrHigher<P, T> const& z() const;
  template<size_t P=N>
  Enable3DOrHigher<P> setZ(T const& t);

  template<size_t P=N>
  Enable4DOrHigher<P, T> const& w() const;
  template<size_t P=N>
  Enable4DOrHigher<P> setW(T const& t);
};

最佳答案

我不会将其称为模式,但它是一种已知技术。

通常被称为条件接口(interface) 这种技术主要解决编译时切换机制来打开和关闭类接口(interface)的问题。整个过程提供的工具还可以切换成员的存在(因此术语条件编译 诞生)。

该技术或多或少地按照您建议的方式实现(尽管在 c++11 之前缺少别名模板不是问题),通常的问题是繁重、困惑、困惑和“丑陋”的模板机械样板代码。

解决这个问题,A.亚历山大列斯库 gave a presentation关于这个话题。最初有一小部分提到对这种技术的需求:

enter image description here

子弹说

  • 此函数仅适用于数字

指的是您的技术以及需要编译时条件来切换函数的存在(条件接口(interface))。

谈话继续到新语言功能的提案。既然我们都发明了几次轮子,他说,为什么不使用一种新的语言语法,这将使我们能够执行这样的事情。他的joint workH. Sutter 生成了 static if 一个编译时切换器,它将消除您提到的解决方法的需求。一个简单的用法是

template<int D>
struct Vector
{
    double coordinates[D];
    static if ( D ) {
        double x() { return coordinates[0]; }
    }
    static if ( D > 1 ) {
        double y() { return coordinates[1]; }
    }
    static if ( D > 2 ) {
        double z() { return coordinates[2]; }
    }
};

好吧,也许这不是最聪明的用法,但我想我正在传达这个想法。

现在在对面,B. Stroustrup 发表了 paper在了解 static if 正在解决的问题后,他解释了为什么这是一个有缺陷的概念(双关语意:))并且它的采用对语言来说将是一场灾难(哎哟!)。

这是我的两分钱,从这个“对话”中参与者的水平来看,我想得到一些关于他们站在哪一边的反馈,或者如果他们是标准化过程的一部分,那么什么会他们正在投票。

关于c++ - 这个 SFINAE 模式有名字吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23073931/

相关文章:

design-patterns - 服务器控件如何违反 MVC 设计模式?

c++ - 为什么重载operator<<时需要friend关键字?

c++ - 链接器错误 Lua 5.1

c++ - 尝试向模板函数添加多态性

c++ - C++ 的 Apple mach-o 链接器 (id) 错误

java - 使用 Java 设计读取器和处理器

c# - child 对象与 parent 的沟通模式

c++ - 使用 XGrabKey 或 XGrabKeyboard 重定向键盘输入

c++ - 在子类的子类中使用基类 C++ 的虚方法

c++ - 使用模板在编译时初始化数组指针的 const vector