问题标签 [sfinae]

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 投票
28 回答
244960 浏览

c++ - 如何向 C++ 应用程序添加反射?

我希望能够自省 C++ 类的名称、内容(即成员及其类型)等。我在这里说的是本地 C++,而不是托管 C++,它有反射。我意识到 C++ 使用 RTTI 提供了一些有限的信息。哪些额外的库(或其他技术)可以提供这些信息?

0 投票
17 回答
103510 浏览

c++ - 检查一个类是否具有给定签名的成员函数

我要求一个模板技巧来检测一个类是否具有给定签名的特定成员函数。

这个问题类似于这里引用的问题 http://www.gotw.ca/gotw/071.htm 但不一样:在 Sutter 的书中,他回答了一个类 C 必须提供一个成员函数的问题一个特定的签名,否则程序将无法编译。在我的问题中,如果一个类具有该功能,我需要做一些事情,否则做“其他事情”。

boost::serialization 也面临类似的问题,但我不喜欢他们采用的解决方案:一个模板函数默认调用具有特定签名的自由函数(您必须定义),除非您定义特定的成员函数(在他们的情况下,“序列化”采用给定类型的 2 个参数)具有特定签名,否则会发生编译错误。那就是实现侵入式和非侵入式序列化。

我不喜欢这个解决方案有两个原因:

  1. 为了非侵入性,您必须覆盖 boost::serialization 命名空间中的全局“序列化”函数,因此您可以在您的客户代码中打开命名空间提升和命名空间序列化!
  2. 解决这个混乱的堆栈是 10 到 12 个函数调用。

我需要为没有该成员函数的类定义自定义行为,并且我的实体位于不同的命名空间中(并且我不想在另一个命名空间中覆盖在一个命名空间中定义的全局函数)

你能给我一个提示来解决这个难题吗?

0 投票
33 回答
198418 浏览

c++ - 模板化检查是否存在类成员函数?

是否可以编写一个模板来根据类上是否定义了某个成员函数来改变行为?

这是我想写的一个简单的例子:

因此,如果class TtoString()定义,则使用它;否则,它不会。我不知道该怎么做的神奇部分是“FUNCTION_EXISTS”部分。

0 投票
3 回答
3183 浏览

c++ - 使用 SFINAE 检测 C++ 中类型的 POD-ness

这里的原标题是 Workaround for SFINAE bug in VS2005 C++

这是对 SFINAE 的尝试性使用,以等效于 TR1 中存在的 is_pod 模板类(在 VS2005 中还没有 TR1)。当模板参数是 POD 类型(包括原始类型和由它们构成的结构)时,它的值成员应该为true,而在不是时(如非平凡的构造函数),它的值成员应该为 false。

问题是,不仅 VS 2005 没有 TR1,它也不关心上面的联合(当模板参数不是 POD 时它不应该是有效的),所以 a 和 b 都评估为 true。


感谢您在下面发布的答案。在仔细阅读它们(和代码)之后,我意识到我试图做的确实是一个错误的方法。这个想法是将 SFINAE 行为与对模板must_be_pod的适应结合起来(我在Imperfect C++一书中找到了它,但它也可以在其他地方找到)。实际上,这需要一套非常特殊的 SFINAE 规则,这显然不是标准定义的。毕竟,这并不是 VS 中的真正错误。

0 投票
4 回答
1786 浏览

c++ - 用于 stl 算法的 C++“智能”谓词

我需要为 stl 算法设计谓词,例如 find_if、count_if。

但是我需要它根据 TElement 中某些特定方法的存在而具有不同的运算符 ()。就像它有“getData”一样,我想检查该数据,如果没有,我会做一些其他的动作。

我知道 SFINAE。但我没有 boost:: 项目。所以要么有一些简单的模板“has_method”实现,要么你知道一些其他的设计解决方案。

我不能指向特定类型并简单地重载,因为我想将此 Predicate 放在项目库之一中,该项目库不知道那些具有“getData”方法的特定类。

只要没有命名空间,具有类特征的解决方案就很好。“lib”命名空间中的谓词查找器和具有“getData”的类位于“program”命名空间中。

谢谢。

0 投票
3 回答
2776 浏览

c++ - 具有无效函数类型或数组类型参数的 SFINAE?

请考虑以下代码:

我预计它会做 SFINAE 并选择第二个重载,因为替换TT[1]产量

当然,这是无效的类型。在将模板参数替换为函数参数并检查有效的结果类型(如 14.8.2 [temp.deduct] 描述)之后,完成参数类型(数组->指针)的调整。

但是 comeau 和 GCC 都无法编译上述内容。两者都有不同的诊断。

科莫 说:

“ComeauTest.c”,第 2 行:错误:不允许使用函数数组char (&f(T[1]))[1];

GCC 说(版本4.3.3):

错误:ISO C++ 禁止零大小数组c

意思是,GCC 没有替换失败,但是它选择了 的第一个重载f,返回sizeof1 的 a,而不是像 Comeau 那样没有替换它。

什么编译器是正确的,我的代码是否有效?请在您的答案中参考或引用适当的标准部分。谢谢!


更新:标准本身在列表中包含这样一个示例14.8.2/2。我不知道,为什么我首先忽略了它:

虽然这个例子只是提供信息,但它显示了所有这些神秘段落的意图,并且似乎表明上面的代码应该可以工作并拒绝第一个重载。

0 投票
10 回答
55891 浏览

c++ - C++ SFINAE 示例?

我想进入更多的模板元编程。我知道 SFINAE 代表“替代失败不是错误”。但是有人可以告诉我 SFINAE 的好用处吗?

0 投票
10 回答
43795 浏览

c++ - 如何检测类中是否存在特定的成员变量?

为了创建算法模板函数,我需要知道作为模板参数的类中的 x 或 X(以及 y 或 Y)。在将我的函数用于 MFC CPoint 类或 GDI+ PointF 类或其他一些类时,它可能很有用。他们都在其中使用不同的 x。我的解决方案可以简化为以下代码:

但它不能在 Visual Studio 中编译,而在 GNU C++ 中编译。使用 Visual Studio,我可以使用以下模板:

但它不能在 GNU C++ 中编译。有通用的解决方案吗?

UPD:此处的结构 P1 和 P2 仅作为示例。可能有任何具有未知成员的类。

PS 请不要在此处发布 C++11 解决方案,因为它们很明显且与问题无关。

0 投票
3 回答
1956 浏览

c++ - 为什么有时需要写 `typename T` 而不仅仅是 `T`?

我正在阅读有关SFINAE的 Wikipedia 文章并遇到以下代码示例:

现在我实际上以前写过这样的代码,不知何故我直觉地知道我需要输入“typename T”而不仅仅是“T”。但是,很高兴知道它背后的实际逻辑。有人愿意解释吗?

0 投票
0 回答
3960 浏览

c++ - 判断一个类是否有函数

使用技巧(由Olivier Langlois描述),我可以确定一个类是否定义了类型:

我还可以确定一个类是否有变量:

但是,decltype(c::func)nur decltype(c::func())(取决于参数)都不适用于成员函数。有没有办法做到这一点,还是我必须在每个类中创建一个仿函数并用 检测它typename C::functor

编辑:你们都是对的,但是因为我还必须测试我将使用的类型decltype(&C::func)(这显然应该是一个指针)。