[英]Using C++ std::enable_if with a normal function?
假設我有一個枚舉:
typedef enum {
Val1,
Val2,
Val3,
Val4
} vals;
並且函數check(vals x)
返回一個布爾值,指示val是否在vals
中的特定值子集中。
bool check(vals x) {
switch(x) {
case Val1:
case Val3:
return true;
}
return false;
}
我想使用這個函數作為enable_if
的條件(正如你所看到的那樣,它不是一個函數,取決於運行時),讓用戶只使用帶有類模板的那些值。
class MyClass<vals v> {
}
PS:我需要模板來為類的方法進行特化,具體取決於模板值。
在C ++ 14中,只需聲明函數constexpr
並保持實現不變。
在C + 11中,您需要將其更改為單個return語句:
constexpr bool check(vals x) {
return x == Val1 || x == Val3;
}
您既不需要函數也不需要enable_if
來執行此操作。
這是一個例子:
enum class vals {
Val1,
Val2,
Val3,
Val4
};
template<vals v, bool = (v == vals::Val1 || v == vals::Val3)>
class MyClass;
template<vals v>
class MyClass<v, true> { };
int main() {
MyClass<vals::Val1> ok;
// MyClass<vals::Val2> ko;
}
這個解決方案實際上有一個問題: MyClass<vals::Val2, true> ok;
是一個有效的聲明。
無論如何,如果它適合,主要取決於真正的問題。
如果要使用enable_if
,可以執行以下操作:
#include<type_traits>
enum class vals {
Val1,
Val2,
Val3,
Val4
};
template<vals v, std::enable_if_t<(v == vals::Val1 || v == vals::Val3)>* = nullptr>
class MyClass { };
int main() {
MyClass<vals::Val1> ok;
// MyClass<vals::Val2> ko;
}
另一個解決方案是使用static_assert
:
enum class vals {
Val1,
Val2,
Val3,
Val4
};
template<vals v>
class MyClass {
static_assert((v == vals::Val1 || v == vals::Val3), "!");
};
int main() {
MyClass<vals::Val1> ok;
// MyClass<vals::Val2> ko;
}
等等,存在許多不需要constexpr
功能的替代方案。
否則,讓函數成為@nm所提及的constexpr
,這就是全部。
謝謝你的回答。 我找到了另一種解決方案,可能對我的問題更好。 由於我必須為所有支持的值實現專門的方法,我甚至可以在非專用方法中設置斷言。
template<vals v>
MyClass<v>::method() {
assert(check(v) && "Unsupported value!");
}
template<>
MyClass<Val1>::method() {
// do it!
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.