c++ - 使用 std::enable_if 的正确方法
问题描述
这些类之间有什么区别?正是这些方法与 enable_if。
/// Alias of std::enable_if...
template <bool B, typename T = void>
using Enable_if = typename std::enable_if<B, T>::type;
Template<typename T, std::size_t N>
class A {
...
template <std::size_t NN = N,
typename = Enable_if<NN == 2>>
Some_Return_Type
method(param1, param2)
{}
template <std::size_t NN = N,
typename = Enable_if<NN == 1>>
Some_Return_Type
method(param1)
{}
};
Template<typename T, std::size_t N>
class B {
...
Enable_if<N == 2, Some_Return_Type>
method(param1, param2)
{}
Enable_if<N == 1, Some_Return_Type>
method(param1)
{}
};
在我有的情况下,使用 enable_if 的正确方法是什么:
- 至少有 2 个方法仅在参数上有所不同,并且它们具有相同的名称,但其中只有一个必须是“活动的”(如果 N == 1 其中一个,如果 N == 2 另一个)。
- 只有一种方法在 N == 0 时有效,而在其他情况下无效。
我想得到类似的东西:
Obj<int, 2> obj2;
Obj<int, 0> obj0;
Obj<int, 1> obj1;
如果我在 IDE 中编写,obj0.
它只显示N == 0
; obj1.
只是N == 1
,……
谢谢。
解决方案
请注意,enable_if
旨在触发 SFINAE:如果模板参数替换在其直接上下文中失败,则不是编译错误。
这正是发生的情况class A
:当用户调用时a.method(...)
,编译器尝试实例化成员函数模板method
,NN
用常量替换参数,这可能会失败。
但是,如果B::method
在类模板B
实例化期间发生“错误”替换,则当编译器替换N
. 失败发生在远离参数的直接上下文的地方,在这种情况下是template<typename T, std::size_t N> class B
。
这就是为什么在第二种情况下你会得到一个编译错误,而不是 SFINAE。
因此,要根据类模板参数启用/禁用成员函数,请使用第一种方法,根据需要组合条件。例如:
template <typename T, std::size_t N>
class A {
template <std::size_t NN = N, typename = std::enable_if_t<NN == 2 || NN == 0>>
void method(int, int)
{}
template <std::size_t NN = N, typename = std::enable_if_t<NN == 1 || NN == 0>>
void method(int)
{}
};
更新: enable_if 如何工作。大致可以这样实现:
template<bool, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> {
using type = T;
};
请注意,如果第一个参数是false
,enable_if
没有 inner type
,那么格式错误enable_if<false, int>::type
。这就是触发 SFINAE 的原因。
推荐阅读
- javascript - MongoDB 可以接受哪些 JS 类型?
- python - Asyncio/Discord.py:使用 loop.create_task() 发出任务,其优先级/速度与 await 相同
- ruby-on-rails - 导轨用防护装置代替箱体
- asp.net-mvc - Asp.Net Core MVC 和重定向和路由
- django - 如何破坏动态模型?
- django - 如何在 Django 中查询三个模型相互关联的位置?
- powerbi-desktop - Power BI Desktop,从 SQL 数据库导入数据并构建历史记录
- sql - GridDB 是否支持数据加密?
- matplotlib - 如何根据分类变量将标题设置为 lmplots?
- r - 有影响的案例——glmer