[英]Using C++ std::enable_if with a normal function?
let's say I have an enumeration: 假设我有一个枚举:
typedef enum {
Val1,
Val2,
Val3,
Val4
} vals;
And a function check(vals x)
which returns a boolean indicating whether the val is in a specific subset of values in vals
. 并且函数
check(vals x)
返回一个布尔值,指示val是否在vals
中的特定值子集中。
bool check(vals x) {
switch(x) {
case Val1:
case Val3:
return true;
}
return false;
}
I want to use this function as a condition for the enable_if
(the function, as you can see, it's not a function depending on the runtime), to let the users use only those values with the class template. 我想使用这个函数作为
enable_if
的条件(正如你所看到的那样,它不是一个函数,取决于运行时),让用户只使用带有类模板的那些值。
class MyClass<vals v> {
}
PS: I need the template to make specializations for a method of the class, depending on the template value. PS:我需要模板来为类的方法进行特化,具体取决于模板值。
In C++14, just declare the function constexpr
and keep the implementation as is. 在C ++ 14中,只需声明函数
constexpr
并保持实现不变。
In C+11 you need to change it to a single return statement: 在C + 11中,您需要将其更改为单个return语句:
constexpr bool check(vals x) {
return x == Val1 || x == Val3;
}
You don't need neither a function nor enable_if
to do that. 您既不需要函数也不需要
enable_if
来执行此操作。
Here is an example: 这是一个例子:
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;
}
This solution has actually a problem: MyClass<vals::Val2, true> ok;
这个解决方案实际上有一个问题:
MyClass<vals::Val2, true> ok;
is a valid statement. 是一个有效的声明。
Anyway, if it fits well mostly depends on the real problem. 无论如何,如果它适合,主要取决于真正的问题。
If you want to use enable_if
you can do this: 如果要使用
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;
}
Another solution would be using a static_assert
: 另一个解决方案是使用
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;
}
And so on, there exist a bunch of alternatives that does not require a constexpr
ed function. 等等,存在许多不需要
constexpr
功能的替代方案。
Otherwise let the function be constexpr
as mentioned by @nm and that's all. 否则,让函数成为@nm所提及的
constexpr
,这就是全部。
Thanks for the answer guys. 谢谢你的回答。 I found another solution that could be even better for my problem.
我找到了另一种解决方案,可能对我的问题更好。 Since I have to implement a specialized method for all of the supported values, I can even put an assertion in the unspecialized method.
由于我必须为所有支持的值实现专门的方法,我甚至可以在非专用方法中设置断言。
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.