尝试使用SFINAE禁用功能时,是否创建了未定义的行为?

纯娱乐

我试图使用SFINAE禁用基于某些非模板枚举参数的类的某些功能。

下面的代码确实不是用gcc编译,但似乎使用MSVC编译器时,预期编译和工作。

#include <iostream>
#include <type_traits>

enum class B { VARIANT1, VARIANT2 };

template<B B_VAL>
struct A {
    template<class = std::enable_if_t<B_VAL == B::VARIANT1>>
    void func1() {
        std::cout<<"VARIANT1"<<std::endl;
    }
    template<class = std::enable_if_t<B_VAL == B::VARIANT2>>
    void func2() {
        std::cout<<"VARIANT2"<<std::endl;
    }
};

int main()
{
    A<B::VARIANT1> a;
    a.func1();
}

预期的(和msvcs)行为​​是,调用其enable_if_t条件等于false的函数会导致编译时错误,或者如果示例中存在重载函数,则将候选函数删除以解决重载。在所有其他情况下,代码应正常编译。

另一方面,gcc告诉我在func2模板中的enable_if_t的“ struct std :: enable_if <false,void>”中找不到名为“ type”的类型,这与名为“如果条件等于true,则仅在enable_if中存在“类型”。但是,这不是SFINAE功能的理想行为吗?编译器是否应该忽略func2,因为它从未被调用过?

我现在有三个问题:

  1. 由于两个编译器产生不同的行为,它是未定义的吗?如果是,则哪些部分/语句是未定义的?

  2. SFINAE是否适合实现我的目标,还是我误解了它的用例?

  3. 通过使用静态断言作为替代,我会更好吗?

我很抱歉,如果这个问题是一个重复的这一个,但我不认为答案有提供与我的问题有很大帮助。

讲故事的人-Unslander Monica

海湾合作委员会是正确的。这是因为您没有将SFINAE用于您的功能。您这样做似乎是因为您使用了标准库中的SFINAE实用程序,但是这里缺少关键要素。

“ SFINAE”中的“ S”代表替代。将模板参数替换为我们要实例化的模板的参数。现在,有问题的模板是func2为了使SFINAE正常工作,func2必须使用的参数替换其参数。但在这里

std::enable_if_t<B_VAL == B::VARIANT2>

没有正在func2使用的参数它不依赖于替换为期间发生的任何事情func2这只是一个无效类型,完全独立于实际实例化的尝试func2

虽然不难修复

template<B B_VAL_ = B_VAL, class = std::enable_if_t<B_VAL_ == B::VARIANT1>>
void func1() {
    std::cout<<"VARIANT1"<<std::endl;
}

template<B B_VAL_ = B_VAL, class = std::enable_if_t<B_VAL_ == B::VARIANT2>>
void func2() {
    std::cout<<"VARIANT2"<<std::endl;
}

现在,检查是针对将其替换为正确的模板。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

尝试调用单独的函数时未定义的行为

std :: underlying_type:SFINAE是否可以防止未定义的行为?

尝试创建函数时出现“未定义”

尝试创建 docker 容器功能应用程序,当我执行 docker run 时收到错误“未定义存储”

使用 fgetc(stdin) 时的未定义行为

在尝试使用Firebase创建帐户时创建用户文档时出现“无法读取未定义的属性'user'”

gcc -O2创建了一个无限循环,可能是由于行为未定义

尝试使用 reactstrap DropdownMenu 时,`popperManager 未定义`

尝试使用onChange填充变量时未定义的变量

尝试使用Cython扩展时的未定义符号

尝试使用@foreach时出现“未定义的变量:用户”

尝试使用导航栏时未定义的索引

strcat时未定义的行为

尝试在 React 中的功能组件内使用道具时,我收到 TypeError:无法设置未定义的属性“道具”?

使用从操作符new返回的指针作为数组元素的指针时,它是否是未定义的行为

当位被屏蔽时使用不正确的格式说明符是否是未定义的行为

我使用laravel护照创建了API身份验证。当授权令牌出错时,会向我发送错误消息“未定义路由[登录]”

尝试检查属性是否未定义时如何防止“无法读取未定义的属性示例”

未定义的行为

测试功能时未定义

尝试在Javascript中重现功能管道时为“未定义”

尝试在React / Redux / Jest中测试调度动作功能时获取未定义的.then

编写3条指令时是否用逗号`,`分隔未定义的行为?

当p指向字符时,strcmp(p,“ \ n”)行为是否未定义?

在Java中解引用`null`时是否可能产生未定义的行为?

使用jQuery禁用功能

尝试在 MSSQL 中使用 FOR JSON 并尝试读取根密钥时接收未定义

使用 C 语言并打开 MP 时超出特定矩阵长度时的未定义行为

尝试创建Google图表时遇到错误Uncaught TypeError:无法读取未定义的属性'arrayToDataTable'