std::enable_if 与非直接上下文中的硬错误

阿德里安

根据SFINAE对cpprefence的描述

只有函数类型或其模板参数类型或其显式说明符 (C++20 起)的直接上下文中的类型和表达式中的失败是 SFINAE 错误。如果对替换类型/表达式的评估导致副作用,例如某些模板特化的实例化、隐式定义的成员函数的生成等,则这些副作用中的错误将被视为硬错误。

特别是,当Helper<T>我在下面的代码中在模板参数推导期间实例化时,正如预期的那样,我收到错误。所以这是我的问题:为什么std::enable_ifSFINAE 可以很好地工作,即使它是一个必须实例化的结构(并且通常与许多也在此过程中实例化的类型特征结构一起使用)。

这是代码

#include<iostream>
#include<type_traits>

template<typename T, typename U = typename T::my_type>
void sfinae(const T&) { std::cout << "template\n"; }

void sfinae(...) { std::cout << "non template\n"; }

template<typename T>
struct Helper{
    using my_type = typename T::my_type;
};

template<typename T, typename U = typename Helper<T>::my_type>
void hardError(const T&) { std::cout << "template\n"; }

void hardError(...) { std::cout << "non template\n"; }


struct NonEmpty{ using my_type=int; };
struct Empty{ };


int main()
{
    NonEmpty ne;
    Empty e;

    sfinae(ne);     //template overload called
    hardError(ne);  //template overload called

    sfinae(e);      //non-template overload called

    hardError(e);   //hard error 

}
杰洛德42

可能的实现std::enable_if

template <bool cond, typename T = void> struct enable_if;
template <typename T> struct enable_if<false, T>{};
template <typename T> struct enable_if<true, T>{ using type = T; };

所以enable_if不会产生硬错误。实例化std::enable_if<false>是有效的。

实例化Helper<Empty>会在 上产生错误Empty::type,这不是在SFINAE 的直接上下文中完成的,因此是硬错误。

std::enable_if并且std::void_t与 SFINAE 配合得很好,因为它们提供了在直接上下文中失败的简单方法:

std::enable_if<cond_v<T>, int>::type = 0typename AlwaysVoid = std::void_t<decltype(dependent_expression)>

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

std :: enable_if <>的错误

用`std :: enable_if`和非推导上下文重载函数模板

引入std :: enable_if后出现“ No match”错误

C ++ std :: enable_if ....否则?

std :: enable_if如何工作?

std :: conditional vs std :: enable_if

这些是std :: enable_if的预期错误,还是我使用不正确?

防止编码器错误 - 忘记在“std::enable_if<>::type”(SFINAE)中添加“::type”

尝试使用SFINAE(std :: enable_if)和模板特化时出现编译错误

在模板函数返回类型上使用std :: enable_if以利用SFINAE-编译错误

使用 std::enable_if 重载函数以避免模板替换错误

std::enable_if 在模板类中的同名函数上使用时产生错误

使用std :: enable_if限制派生类的模板参数时发生编译错误

正确使用std :: enable_if的方法

处理 std::enable_if<...> 中谓词的逻辑“OR”

SFINAE std :: enable_if参数内

带有多个或条件的 std::enable_if

std :: enable_if如果参数是函数?

在std :: enable_if中使用sizeof ...

C ++-更多类型的std :: enable_if

SFINAE:std :: enable_if作为函数参数

std :: enable_if的基本用法有问题

基于可变模板存在的std :: enable_if

错误:名称空间“ std”中没有名为“ enable_if_t”的模板;你是说'enable_if'吗?

std :: enable_if和std :: shared_ptr

修复第三方代码:“错误:名称空间“ std”中的“ enable_if”未命名模板类型”

std :: is_constructible直接上下文和朋友声明

使用`std :: enable_if`完全禁用构造函数

MSVC 2013'类型':不是'std :: enable_if <false,void>的成员