gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 14:42:22 25 4
gpt4 key购买 nike

我试图使用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 ”中找不到名为“type”的类型,这与名为“如果条件等于true,则仅在enable_if中存在“类型”。但是,这不是SFINAE功能的理想行为吗?编译器是否应该忽略func2,因为它从未被调用过?
我现在有三个问题:
  • 由于两个编译器产生不同的行为,它是未定义的吗?如果是,则哪些部分/语句是未定义的?
  • SFINAE是否适合实现我的目标,还是我误解了它的用例?
  • 通过使用静态断言作为替代会更好吗?

  • 很抱歉,如果这个问题是 this one的重复,但是我认为那里的答案对我的问题没有太大帮助。

    最佳答案

    海湾合作委员会是正确的。这是因为您没有将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;
    }
    现在,检查是针对将其替换为正确的模板。

    关于c++ - 尝试使用SFINAE禁用功能时,是否创建了未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63132268/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com