问题标签 [enable-if]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
977 浏览

c++ - 可选地支持模板的 initializer_list 构造可能包装容器

如果我有一个包装标准容器的模板,我似乎可以相当容易地委托 initializer_list 构造函数:

例如,这可以很好地与 std::vector 一起使用。

但它显然不适用于 T as 'int',或任何其他没有嵌套 value_type typedef 的类型。所以,我想使用某种 enable_if 或类似的技巧来使 initializer_list 构造函数不被发出,除非 T 都定义了嵌套的 value_type typedef,并且可以从 std::initializer_list 构造。

我尝试了以下方法,但它仍然不起作用,因为编译器(在我的情况下是 clang++ 3.1)在 T 为 int 时仍然会绊倒无效的 T::value_type:

关于如何表达概念的任何想法“给 T 上的这个模板一个基于 T 的 value_type 的初始化列表构造函数,当且仅当 T 具有 value_type typedef 并且可以从 T::value_type 的 initializer_list 构造”。

0 投票
1 回答
4040 浏览

c++ - 如果向量是特定长度,则使用 C++11 std::enable_if 启用成员函数

我正在编写一个简单的向量类,我想要一些仅在特定长度的向量中可用的成员函数(例如,三元素向量的叉积)。我偶然发现了 std::enable_if ,它看起来可以做我想做的事,但我似乎无法让它正常工作。

上面的代码编译并正确运行,但是如果我取消注释Vector<double,4> v4我在编译时收到以下错误:

有人能指出我哪里出错了吗?

0 投票
5 回答
24756 浏览

c++ - 为什么用 enable_if 编译错误

为什么这不能用 gcc48 和 clang32 编译?

海合会错误:

叮当错误:

编辑 - 解决方案

我已经接受了 Charles Salvia 的回答,但出于实际原因,我无法使用建议的解决方法(专门研究 N)。我找到了其他适合我的解决方法。使enable_if依赖T

0 投票
4 回答
39044 浏览

c++ - 为什么我应该在函数签名中避免 std::enable_if

Scott Meyers 发布了他的下一本书 EC++11 的内容和状态。他写道,书中的一项内容可能是“Avoid std::enable_ifin function signatures”

std::enable_if可以用作函数参数、返回类型或类模板或函数模板参数,以有条件地从重载决议中删除函数或类。

这个问题中,显示了所有三个解决方案。

作为函数参数:

作为模板参数:

作为返回类型:

  • 应该首选哪种解决方案,为什么要避免使用其他解决方案?
  • 在哪些情况下, “在函数签名中避免std::enable_if”涉及用作返回类型(这不是正常函数签名的一部分,而是模板特化的一部分)?
  • 成员函数模板和非成员函数模板有什么区别吗?
0 投票
1 回答
588 浏览

c++ - enable_if + type 模板,没有 SFINAE(没有 boost 的 enable_if_c ?)

我通过阅读各种帖子了解到以下内容不应该编译。

尽管如此,clang 3.2 还是接受了这个代码版本并且运行良好。我的理解是它在后台使用了 enable_if_c 的内部版本。现在我想在不接受它的 gcc 下进行编译。我知道拥有一个实际类型并按照其他帖子使用 SFINAE 会很好。

就我而言:

  • 我正在尝试定义一个运算符,因此我不能对具有某些默认类型/值的额外参数大惊小怪-> 似乎我不能使用 SFINAE。
  • 我也不能使用继承,因为我必须保留一切 constexpr。
  • 由于项目要求,我不能在我的代码 (enable_if_c) 中使用任何增强功能

我有出路吗?

0 投票
1 回答
951 浏览

c++ - 正确签名/检测 Container::reserve() 的存在

给定一个C符合 STL 的容器类型,我如何正确检测是否C包含成员函数reserve?我尝试了以下方法(使用 GCC 4.6.3):

这适用于Cbeing std::vector,但不适用于无序容器,例如std::unordered_set。原因是,那reserve是 的(直接)成员函数std::vector,但对于无序容器,它是从基类继承的,即它的签名不是void (C::*)( typename C::size_type ),而是void (B::*)( typename C::size_type )针对 的某些未指定的基BC

我知道如何解决它并检测reserve即使是继承的,但它看起来很笨拙,我想知道标准允许什么。所以...

我的问题是:标准是否允许reserve从未指定的基类继承,还是概要绑定并需要直接成员函数?

0 投票
1 回答
119 浏览

c++ - enable_if boost::fusion 可调用

有没有办法专门为 boost::fusion 可调用对象使用 enable_if?

这里F是一个融合“融合函数”可以取任意序列作为参数

0 投票
2 回答
5551 浏览

c++ - 将 std::tuple 用于模板参数列表而不是类型列表

我正在尝试调用这样的模板函数:

我知道我可以“简单地”传递元组的类型。这是我所知道的,但这很麻烦,因为我对这个函数做了很多调用,而且元组很长:

所以我尝试了 get 方法的多种实现,但没有成功:

通过模板参数启用

这给了我这个错误:

我不明白为什么缺少模板参数。

所以我尝试了另一种实现:

模板模板命名参数

但后来我得到这个错误:

同样,由于缺少标识符,我不明白错误。

我现在想知道我想要实现的目标是否可能。是否可以使用std::tuple我想要的?或者,还有更好的方法 ?

0 投票
1 回答
1746 浏览

c++ - 检查类型是否被声明为元类型系统(对于 SFINAE)

为了区分使用 SFINAEt类型的参数的大小写T,我想知道语句是否

和/或

编译。如果一个编译,另一个也编译,除非你破解元类型系统。当且仅当T已使用Q_DECLARE_METATYPE(T).

非常简单的使用示例,当且仅当元类型系统支持时,一个人想通过简单地 qDebugging 一个变体包装的等效项来打印值的类型(我不需要这个,但这以最小的形式显示了问题例子):

我知道这样做的几种(但相似的)可能性,但它们都引入了一些辅助结构、复杂的 enable_if 等。现在我知道QTypeInfo,我想已经提供了类似“在 Qt 元类型系统中声明的” “类型特征。然而,这个类没有记录,因此不建议在长期和生产代码中使用它,因为它可能会在 Qt 版本之间发生变化。

T如果QVariant 支持类型,是否有一种非常简单的方法(比使用“检查器”+ enable_if 更简单)来检查 SFINAE 专业化?

请注意,该解决方案仍应可在不同 Qt 版本之间移植(Qt4 和 Qt5 可能使用不同的QTypeInfo定义)。但是,我使用 C++11,所以我可以访问std::enable_if例如。

“不可移植”的方式是使用QMetaTypeId2<T>::Definedin an的内部定义enable_if(它是一个定义为 0 或 1 的枚举值)。因此,一个可行的解决方案是:

然而,由于QMetaTypeId2没有记录并且只是内部的东西,它不应该出现在客户端代码中。

0 投票
1 回答
450 浏览

c++11 - C++11:对无效表达式使用 decltype

假设我有一个结构(在现实生活中,这是一个自动机):

为此,我想提供一个可以看到它转置(iow、反转或镜像)的视图。因为我有不止一个automaton类,我有一个类模板来包装我的自动机(我真的想要组合,而不是继承),并将所有函数调用反弹到包装的自动机,颠倒需要的东西。为了简单起见,在这里,它只是转发呼叫。

用手,我会得到

但是有很多函数,我不想在包装器中硬编码这么多信息(函数签名)。多亏了可变参数模板和对传入参数的完美转发,decltype对于结果,很容易有一个宏来分解所有 const 成员函数的定义,而另一个宏则用于非常量成员函数(不同之处在于const)。基本上,在这种情况下,它归结为:

这适用于非常量自动机,但如果我包装一个 const 自动机就会中断:

我的编译器抱怨(G++ 4.9):

和(Clang++ 3.3):

他们是对的!中的表达式decltype打破了包装自动机的 const-ness。然而,我发誓我不会使用这个功能。就像我不会使用手工包裹的相应的一样。

所以我的问题是:有没有办法编写包装的定义,set_final这样我就不必拼出它的签名(输入和输出)?我曾尝试使用std::enable_if,但它对这里的问题没有任何改变。无论如何,它需要编译器是惰性的,并且接受不评估第二个参数std::enable_if是否不需要......

提前致谢。