在“太阳底下没有新鲜事”的规则下运作,我怀疑我是第一个想出这个把戏的人。我想我最终会偶然发现一些在线记录它的东西,但我还没有,所以我想我会问。
它的目的是在不使用派生类的情况下有选择地启用某些相关的功能。
这个图案有名字吗?有没有人有任何关于这种模式或类似运作模式的有用信息?
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关于这个话题。最初有一小部分提到对这种技术的需求:
子弹说
- 此函数仅适用于数字
指的是您的技术以及需要编译时条件来切换函数的存在(条件接口(interface))。
谈话继续到新语言功能的提案。既然我们都发明了几次轮子,他说,为什么不使用一种新的语言语法,这将使我们能够执行这样的事情。他的joint work与 H. 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/