在「太陽下沒有新東西」的規則下運作,我懷疑我是第一個想出這個竅門的人。我想我會偶然在網上記錄它,但我還沒有,所以我想我會問。這個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);
};
這是一個有趣的想法 - 本質上參數化成員函數指針。在JavaScript中,您可以構建「原型」對象,從而有條件地創建某些成員函數。我在C++中沒有見過類似的東西。好奇地看到回覆...... –
對此的激勵用例是我們也有多維線和盒類,它們都採用了標準點,但是我們之前有過派生類的point2和point3,所以有用的2d和3d點函數對類本身來說都是不可訪問的(除非我們也要派生它們,在這種情況下,它將是一個重新實現,因爲成員已經改變了,並且有很多通用代碼,DRY),而且還包含任何代碼片段使用框和線算法。所以我們覺得使用SFINAE更清潔,即使它使得暴露的函數稍微不一致。 – OmnipotentEntity
爲什麼要重複使用'enable_if'成爲一種模式?這是'enable_if'的典型應用 - 例如考慮[cppreference的描述](http://en.cppreference.com/w/cpp/types/enable_if)「*有條件地從基於類型特徵的重載解析中移除函數和類,併爲不同類型特徵提供單獨的函數重載和特化*「......似乎包含了你所做的完全充分的事情。 –