【问题标题】:SFINAE using std::enable_if: type parameter vs non-type parameterSFINAE 使用 std::enable_if:类型参数与非类型参数
【发布时间】:2021-02-08 12:01:02
【问题描述】:
template<bool F, typename = std::enable_if_t<F>>
auto func1() -> int { return 0; }
template<bool F, typename = std::enable_if_t<!F>>
auto func1() -> int { return 0; }

template<bool F, std::enable_if_t<F, int> = 0>
auto func2() -> int { return 0; }
template<bool F, std::enable_if_t<!F, int> = 0>
auto func2() -> int { return 0; }

这里有两组重载函数:func1()func2()func1() 对 SFINAE 使用类型参数,func2() 对 SFINAE 使用非类型参数。

编译这些函数时,func1() 会导致编译错误,但func2() 不会。为什么 SFINAE 对 func2() 有效而对 func1() 无效?

【问题讨论】:

    标签: c++ templates sfinae non-type-template-parameter


    【解决方案1】:

    因为在第一种情况下,SFINAE 失败只会删除模板参数的默认值。

    // in case F is true, you have 
    
    template <bool F, typename = void>
    int func1() { return 0; }
    
    template <bool F, typename> // no more default  but still available
    int func1() { return 0; }
    

    因此不会禁用该功能,并且您对同一功能有两个定义(默认值不会更改功能签名),因此,正如 Jarod42 所指出的(谢谢),您违反了@987654321 @。

    在第二种情况下,您删除了模板参数,因此您破坏了函数,因此不再发生冲突。

    template <bool F, int = 0>
    int func2() { return 0; }
    
    // template<bool F, ...>  // function removed
    // int func2() { return 0; }
    

    您可以验证,在第一种情况下,“已禁用”功能仍然可用,并使用单个功能进行测试

    template <bool F, typename = std::enable_if_t<F>>
    int foo ()
     { return 0; }
    

    并使用truefalsefalse, void 调用它。

    foo<true>();  // compile: foo<true, void>() called
    foo<false>();  // compilation error: no second template paramenter
    foo<false, void>();  // compile: explicit second template parameter
    

    【讨论】:

    • @Jarod42 - 谢谢。我已经修改了试图表达更好的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2017-09-18
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多