Pregunta

Operating under the rule of "there's never anything new under the sun," I doubt that I'm the first person to come up with this trick. I figured I would stumble across something online documenting it eventually, but I haven't yet, so I figured I would ask.

Its purpose is to selectively enable certain functions provided that they're relevant, without using a derived class.

Is there a name for this pattern? And does anyone have any useful information on this pattern or a pattern that operates similarly?

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);
};
¿Fue útil?

Solución

I wouldn't call it a pattern, but it's a known technique.

Mostly reffered to as conditional interface this technique mainly addresses the problem of a compile time toggling mechanism to switch on and off interfaces of a class. The overall process provides the tools to also toggle the existence of members (so the term conditional compilation gets born).

The technique is more or less implemented the way you propose (though the lack of alias templates was not a problem prior to c++11) and the usual problem is the heavy, cluttering, confusing and "ugly" template machinery boilerplate code.

Addressing this issue, A. Alexandrescu gave a presentation about the topic. Initially there's a small mentioning of the needs for such a technique :

enter image description here

The bullet that says

  • This function works only with numbers

is reffering to your techniques and the need to have compile time conditionals to toggle the existence of functions ( conditional interface ).

The talk goes on to a proposal for a new language feature. Since we all invented the wheel a couple of times he says, why not a new language syntax, that will allow us to perform such things. His joint work with H. Sutter, produced static if a compile time toggler that would remove the needs for workarounds as the one you mention. A simple use of this would be

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]; }
    }
};

OK maybe that's not the smartest use of it but I think I'm communicating the idea.

On the opposing side now, B. Stroustroup has published a paper where after aknowledging the problems static if is addressing, he explains why it's a flawed concept (pun intended :) ) and its adoption would be a disaster for the language (ouch!).

That was my two cents, judging from the level of the participants in this "conversation" I'd like to have some feedback regarding on which side they're on, or if they're part of the standardization process what will they be voting for.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top