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

c++ - SFINAE 使用枚举模板参数失败

有人可以解释以下行为(我使用的是 Visual Studio 2010)。
标题:

来源:

这给出了编译器

但是,如果我将函数模板参数从枚举类型 WeekDay 更改为 int,它编译得很好:

正常的功能模板专业化也可以正常工作,这并不奇怪:

更奇怪的是,如果我将源文件更改为使用除 MONDAY 或 TUESDAY 之外的任何其他工作日,即bool b = goToWork<THURSDAY>();错误更改为:

编辑:也许有人可以使用不同的编译器(Visual Studio 2010 除外)对此进行测试,看看是否会发生同样的事情,因为它似乎没有任何意义

编辑:我发现了这种行为的一个新的“有趣”方面。也就是说,如果我将模板参数与==!=运算符的直接比较更改为与辅助结构模板的比较,它可以正常工作:

编辑:顺便说一句,我做了一个错误报告,这是微软的回答:“这是一个在尝试提升非类型模板参数时出现的错误。不幸的是,鉴于我们对此版本的资源限制并且有效-around 可用,我们将无法在 Visual Studio 的下一版本中修复此问题。解决方法是将模板参数类型更改为 int。

(我认为“此版本”是指 Visual Studio 2010)

0 投票
1 回答
435 浏览

c++ - 检测类是否有重载函数在 Comeau 编译器上失败

我正在尝试使用 SFINAE 来检测一个类是否具有采用某种类型的重载成员函数。我的代码在 Visual Studio 和 GCC 中似乎可以正常工作,但不能使用 Comeau 在线编译器进行编译。

这是我正在使用的代码:

错误消息是:没有函数模板“CallFunc”的实例与参数列表匹配。似乎 HasFunc::Has 对 int 为假,而当它应该为真时为 float。

这是 Comeau 编译器中的错误吗?我在做一些不标准的事情吗?如果是这样,我需要做什么来修复它?

更新

我想现在的问题变成了,如果这是一个错误,我能做些什么来解决它吗?我尝试在 &TestClass::Func 上使用 static_cast,但要么这是不可能的,要么我没有得到正确的语法,因为我无法编译它。

如果这不是解决方案,我是否可以对 TestClass 或 HasFunc 进行任何修改以解决该问题?

0 投票
1 回答
13896 浏览

c++ - 如果在推演过程中无法解析函数的地址,是SFINAE还是编译器错误?

在 C++0x 中,SFINAE 规则已被简化,因此在演绎的“直接上下文”中出现的任何无效表达式或类型都不会导致编译器错误,而是会导致演绎失败 (SFINAE)。

我的问题是:
如果我取了一个重载函数的地址并且它不能被解析,那是在直接推理的上下文中失败吗?
(即如果无法解决,是硬错误还是 SFINAE)?

这是一些示例代码:

Gcc 4.5 声明这是一个编译器错误,并且 clang 吐出了一个断言违规。

以下是一些更相关的感兴趣的问题:

FCD-C++0x 是否清楚地指定了这里应该发生什么?
编译器拒绝此代码是否错误?
是否需要更好地定义演绎的“直接上下文”?

谢谢!

0 投票
4 回答
1806 浏览

c++ - 部分模板特化:匹配特化模板参数的属性

有没有办法定义这样的部分专业化,AA<C, B<P1> >将是A正常的模板,但A<C, B<P2> >会是专业化吗?

针对 Marcelo 进行编辑:更具体地说,不应仅使用 B 选择专业化,还应选择具有特定属性的任何类型,例如它是第一个参数为 P2 的模板。

目标是为Y提供一个漂亮的界面A,允许编写类似A<C, Y<P2,Q> >.


用模板模板参数替换Y模板参数会很好,但是有没有办法在此基础上对其进行部分专门化P

目的是编写如下内容:

编辑以回应 In silico:我说制作模板模板参数会很好Y,但实际上这违背了我想要做的目的,即用于Y将逻辑链接的属性组合在一起,但仍然A基于一个那些子属性。


有没有办法通过将特征添加到专业化template <> class B<P2>然后在中使用 SFINAE A?目的是编写如下内容:

0 投票
1 回答
4036 浏览

c++ - boost::enable_if 类模板方法

我得到了带有模板方法的类,这些方法如下:

显然,两个模板都被实例化,导致编译时错误。模板方法的实例化与自由函数的实例化不同吗?我已经以不同的方式解决了这个问题,但我想知道发生了什么。我唯一能想到的可能会导致这种行为,启用条件不依赖于直接模板参数,而是依赖于类模板参数

谢谢

0 投票
1 回答
617 浏览

c++ - sfinae 是否实例化函数体?

我想使用通常的 SFINAE 技巧来检测一个类的特定成员函数的存在。

应该注意的是,这会检测到一种不同类型的分配器,它具有void* allocate(std::size_t)非标准的成员函数(可能是一些原始内存分配器)。

接下来,我有一个不完整的类型和一个用于该不完整类型的 std::allocator。

我正在检查 test_alloc 是否是我正在寻找的那个。

当我“使用”时肯定struct test会完成,test_alloc例如

在另一个编译单元中。然而,当 has_alloc 测试发生时,编译器尝试实例化 std::allocator 的 allocate 函数,并发现在函数体内使用了不完整类型的 sizeof,并导致硬错误。如果 allocate 的实现在使用时分开并包含在单独的位置,则似乎不会发生错误,例如

test_def.hpp包含

然而,虽然我可以这样做alloc<T>,但因为不可能std::allocator分离出实现是不可能的。我正在寻找的是可以测试一个函数是否void* allocate(size_t)存在于test_alloc. 如果不是,它将测试为否定,如果是,即如果函数签名匹配,即使它不能在那里实例化,也测试为肯定。

0 投票
1 回答
827 浏览

c++ - 在结构偏特化中使用 SFINAE 捕获函子

由于某些复杂的原因,我想将任何支持的类型 T(来自模板)转换为我选择的类型列表。为此,我尝试使用名为“Convert”的模板结构。例如:

以上这些很容易使用模板专业化来实现。但是有一种情况会导致问题:

为了处理这个问题,我想我必须使用SFINAE但我无法让它编译。

下面的代码给了我“部分专业化不能匹配主模板的参数列表”(即禁止写“转换”):

这给了我“模板参数在部分专业化中未使用或可推导”(即它认为未使用 T):

我不知道该怎么做,我所有的尝试都导致了上述两个错误之一。

编辑:我想用相同的模型捕捉其他通用的东西,所以我不能只在非专业结构中写“typedef T type”。

谢谢

0 投票
1 回答
1379 浏览

c++ - SFINAE 检测非成员函数的存在

有没有人知道根据是否定义了非成员方法来专门化模板的方法?我知道如果存在成员函数,有很多方法可以专门化,但我从未见过非成员示例。具体问题是,如果为 T 定义了 operator<<,则为 shared_ptr 专门化 operator<< 以应用 operator<<,否则仅打印指针位置。如果所有类都将 operator<< 定义为成员,那就太好了,但不幸的是,许多类都使用免费函数。我在想像下面这样的东西:

编辑:对于后代,这是可行的解决方案。注意 boost::shared_ptr 已经有一个默认的 operator<< 输出地址,所以 disable_if 是不必要的。由于 operator<< 返回一个引用,所以这是可行的。对于一般情况,我怀疑必须对其进行调整以反映相关函数的返回类型。

0 投票
5 回答
6583 浏览

c++ - 向非 C++ 程序员解释 C++ SFINAE

C++ 中的 SFINAE 是什么?

您能否用不懂 C++ 的程序员可以理解的语言解释一下?另外,SFINAE 对应于 Python 这样的语言中的什么概念?

0 投票
2 回答
259 浏览

c++ - SFINAE:有些失败比其他失败更平等?

我正在尝试使用SFINAE来区分具有名为“名称”的成员的类。我以似乎是标准模式的方式进行了设置,但它不起作用——编译器没有默默地忽略“失败”的替换,而是产生了一个错误。

我确定我遇到了一些模板替换规则,如果有人能解释哪一个,我将不胜感激。

这是一个精简的例子。我正在使用 gcc: