问题标签 [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 投票
2 回答
1376 浏览

c++ - 使用 SFINAE 原理时重载函数不明确

我遇到了一些用 VS7.1 编写的代码,现在我正试图让它在 MacOSX 上工作。我理解的下面的代码片段是关于SFINAE原则的。据我了解,代码用于在编译时通过依赖一些模板实例化魔术来知道某物是什么类型。简而言之,通过查看模板参数来选择正确的重载。

这是我的代码。稍微简化以仅显示问题。

我只是像这样使用它:

编译上述代码时运行良好,并且由于在使用 int 时缺少 Type 的 typedef,它会选择最顶层的类。

如果我现在改用 char ......

...编译器会抱怨 Select functions 模棱两可,因为它不知道该使用哪一个。从我读过的内容来看,重载决议最不喜欢省略号参数(...)。因此,它应该知道选择第一个。

该代码至少在 VS7.1 上运行良好,但在 MacOSX 的 gcc 和 Linux 的 gcc4.4 上不行。

任何建议如何纠正这个问题?也许它通常以另一种方式完成?

谢谢!

更新:我意识到我提供的示例代码可能稍微简化了一点,因为我相信我们不会在这里检查类型,即使我错误地让它看起来像那样。今晚我必须为您收集更多信息,因为我这里没有代码。对此感到抱歉。

UPDATE2:即使我的表现不好,这是由于不熟悉原始代码或以这种方式使用模板。同时我挖掘了更多信息,假设这些构造由于某种原因存在 X 并且我给出的名称都是错误的,那么编译器问题呢?为什么这里不能选择正确的重载函数?这也让我很感兴趣。正如我所说,我会更好地解释总体目标是什么。

编辑

在仔细查看原始代码后,它正在使用 boost::integral_constant 和 boost::enable_if ,就像这里建议的那样。问题是特定于模板参数的推导方式,并且它没有按照设置的方式工作。但是,按照 Georg 在回答末尾的建议,我可以纠正一些事情以接受事情。我现在有以下内容:

这很好用。在进行一些试验时,我发现在 Select 函数中有两个函数参数会导致问题。我还没找到原因。当我更好地理解事情时,我会回到这一点。

感谢你的帮助。至少我现在了解这里的原则以及事情应该如何运作。只是一些细节,还不得而知。

0 投票
2 回答
1470 浏览

c++ - 如何在编译时选择正确的重载函数模板?

我试图了解如何在编译时选择正确的重载函数模板,但编译器让我很难过。我可以让它工作,但我不明白发生了什么。让我解释。

我有两个结构 A 和 B,如下所示。一个具有特殊功能,另一个具有正常功能。

我的意图是有一种机制,它在编译时根据特殊函数是否可用来选择正确的重载函数模板。我运行了两个函数,它们将结构作为参数,因此它们可以调用适当的函数。

我已经用以下方法对此进行了测试,得到了各种结果:

我想在run(a)没有任何额外参数或 <> 的情况下使用它。当这不起作用时,我的代码有问题吗?

另外,我有兴趣了解这里发生了什么以及为什么会推断出这样的事情,所以我需要给予<A>A不是给予B?我不知道标准说什么以及编译器之间是否有所不同,但至少 Linux 上的 gcc4.4.4 和 Mac 上的 gcc 4.0.1 像我所描述的那样工作。

有人可以对此有所了解吗?谢谢!

0 投票
1 回答
230 浏览

c++ - 为什么它有效?SFINAE

请参阅代码中的注释。

0 投票
3 回答
1504 浏览

c++ - 在模板类中隐藏成员函数

是否可以在模板类中隐藏一些成员函数?假设我们有类似的东西:

目标是以某种方式使用这个类,在某些情况下我们只能看到 increment() 函数,而在其他一些情况下我们只能看到 increment(T) 成员函数。为此,我可以考虑使用 SFINAE:

然后使用我的模板,例如:

但是,编译器不允许我这样做。还有其他可行的方法吗?如果成员函数实际上是构造函数,它也会起作用吗?

0 投票
2 回答
3331 浏览

c++ - 使用 SFINAE 检查全局运算符<

我想要几个重载的全局to_string()函数,它们采用某种类型T并将其转换为其字符串表示形式。对于一般情况,我希望能够编写:

has_insertion_operator到目前为止,我的实现是:

(它借用了thisthis。)这似乎行得通。但现在我想要一个重载版本的to_stringfor 类型没有operator<<但有自己to_string() 成员函数,即:

的实现has_to_string是:

(这部分似乎工作正常。它改编自这个。)但是,当我有:

我得到:

似乎 SFINAE 没有发生。如何has_insertion_operator正确编写以确定全局operator<<是否可用?

仅供参考:我使用的是 g++ 4.2.1(作为 Mac OS X 上 Xcode 的一部分提供的版本)。另外,我希望代码只有标准 C++03,没有第三方库,例如 Boost。

谢谢!


第 48 行的初始化程序value不在 SFINAE 工作的上下文中。尝试将表达式移至函数声明。

然而,我不得不质疑这其中的复杂程度。我看到非正交机制会相互磨合(to_stringvs. operator<<),并且我听到一些糟糕的假设被抛来抛去(例如,这operator<<是全局 vs 成员,尽管在这方面实现的代码看起来还不错)。

0 投票
2 回答
2186 浏览

c++ - C++ toString 成员函数和 ostream 运算符 << 通过模板集成

我是一名初学者 C++ 开发人员,我有一个关于通过模板进行操作员集成toString的问题。ostream我有这样的代码:

代码编译无误,应用程序执行成功。使用这种方法好吗?我想在没有任何 boost 帮助的情况下实现它。

0 投票
2 回答
246 浏览

c++ - SFINAE 没有检测到 T::reference

该类std::vector<T>是 STL Container 概念的模型,因此任何适当的 vector 实现都必须包含嵌套的 typedefvalue_type以及reference. 这应该可以使用 SFINAE 检测到。但是,在我自己的测试中,我可以使用 SFINAE 来检测嵌套的value_typetypedef,但由于某种原因我无法检测到reference.

这输出:Has nested typedef!

但是,如果我用 替换value_typereference例如:

...程序根本无法编译,出现错误:error: no matching function for call to test(std::vector<int, std::allocator<int> >)

为什么 SFINAE 技术适用于T::value_type而不适用于T::reference

0 投票
5 回答
8712 浏览

c++ - 使用 decltype/SFINAE 检测操作员支持

一篇(有点)过时的文章探讨了decltype与 SFINAE 一起使用来检测类型是否支持某些运算符的方法,例如==or <

下面是用于检测类是否支持<运算符的示例代码:

这输出true,因为当然std::string支持<运营商。但是,如果我尝试将它与支持该<运算符的类一起使用,则会出现编译器错误:

所以 SFINAE 不在这里工作。我在 GCC 4.4 和 GCC 4.6 上试过这个,都表现出相同的行为。那么,是否可以通过这种方式使用 SFINAE 来检测一个类型是否支持某些表达式呢?

0 投票
1 回答
147 浏览

templates - MSVC10 SFINAE 导致致命错误而不是替换失败

我在这里有一个(相对)简短的代码示例。

MSVC 抛出这个,说那type不是 的成员enable_if<false, int>,这有点意思。我不明白为什么这会导致致命错误而不仅仅是替换失败 - 在 GCC 上,此代码的行为完全符合预期并且可以干净地编译。

0 投票
3 回答
487 浏览

c++ - 使用 SFINAE 的 C++ 中的可移植 typeof()?

可能重复:
C++03 中缺少 typeof 运算符?

是否可以使用模板在 pre-C++0x C++ 中可移植地获取表达式的编译时类型?

就像是:

但由于我们正在使用模板,显然可能需要稍微不同的语法。

(我在这里和网络上的其他地方看到了许多重复项,但它们似乎依赖于编译器特定的功能或 C++0x(C++11?)decltype功能。)