[英]C++: Trying to encapsulate std::enable_if in class
當我有一個光榮的主意將std::enable_if
封裝在這樣的結構中時,我只是使用SFINAE選擇功能模板
template<typename T, typename U>
struct EnableWhenEqual
{
typedef typename std::enable_if<std::is_same<T, U>::value>::type type;
};
然后像這樣使用它
template<typename T, typename U, typename Enable = EnableWhenEqual<T,U>::type >
void foo(T&& t, U&& u)
{
if (std::is_same<T,U>::value)
std::cout << "OK, overload allowed." << std::endl;
else
std::cout << "Bad. Should not compile!" << std::endl;
}
但是,這並不起作用,正如人們通過調用看到的那樣
foo(1,1); //prints "OK, overload allowed"
foo(1,2.0); //prints "Bad, should not compile", but obviously does
另一方面,通過嘗試創建
EnableWhenEqual<int,int>(); //compiles
EnableWhenEqual<int,double>(); //does not compile because type does not exist
一個獲取編譯器錯誤(“類型不是std :: enable_if的成員”)。
這種行為的原因是什么? 我之所以問是因為,根據我對SFINAE的一點了解,我會認為類型推導中的錯誤會導致過載的排除……?
為了完整起見,可以使用模板別名解決以上問題
template <typename T, typename U>
using EnableWhenEqual = typename std::enable_if<std::is_same<T,U>::value>::type;
還有使用結構而不是模板別名的替代方法嗎?
編輯:這里我的意思是解決一般問題的實現。 例如這里
template<typename T, typename U, bool B, typename C=void>
struct EnableWhenEqual {};
template<typename T, typename U, typename C>
struct EnableWhenEqual<T,U,std::is_same<T,U>::value>
{
typedef typename C type;
};
對我不起作用,因為部分專業化需要一個簡單的標識符。 如果可以的話,可以用一般結構Condition<T,U>
替換std::is_same
。 有其他選擇嗎?
這應該可以解決問題:
template<typename T, typename U>
struct EnableWhenEqual : std::enable_if<std::is_same<T, U>::value>
{
};
另一種封裝:
template<class T, class U>
using EnableWhenEqual_t = typename std::enable_if< std::is_same<T,U>::value >::type;
template<typename T, typename U, typename Enable = EnableWhenEqual_t<T,U> >
void foo(T&& t, U&& u) {
if (std::is_same<T,U>::value)
std::cout << "OK, overload allowed." << std::endl;
else
std::cout << "Bad. Should not compile!" << std::endl;
}
注意當您問有關VS處理模板的問題時,請提供確切的Visual Studio版本。 VS模板支持非常古怪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.