C++ SFINAE inside std::enable_if参数
我有不同的视图类型,每个视图类型都有一个C++ SFINAE inside std::enable_if参数,c++,c++11,sfinae,c++17,enable-if,C++,C++11,Sfinae,C++17,Enable If,我有不同的视图类型,每个视图类型都有一个std::size\u t view::dimension成员常量和一个typename视图::value\u type成员类型 以下编译类型检查应验证From和To是否都是视图(使用is\u view进行验证),并且From的内容可以分配给To。(尺寸和可转换值类型相同) Not\u a\u视图不是视图,并在is\u compatible\u视图中导致编译错误。调用view.assign\u from(Not_a\u view())时,SFINAE不适用
std::size\u t view::dimension
成员常量和一个typename视图::value\u type
成员类型
以下编译类型检查应验证From
和To
是否都是视图(使用is\u view
进行验证),并且From
的内容可以分配给To
。(尺寸和可转换值类型相同)
Not\u a\u视图
不是视图,并在is\u compatible\u视图
中导致编译错误。调用view.assign\u from(Not_a\u view())
时,SFINAE不适用,而是在编译器尝试解析第一个assign\u from
函数时发生编译错误
如何编写
与视图兼容
以使其正常工作?在C++17中,std::conjunction
允许这样做吗?一种方法是使用类似于std::conditional
的东西来延迟对类型特征的某些部分的评估,直到我们验证了类型特征的其他部分已经为真
即:
// this one is only valid if From and To are views
template <class From, class To>
struct is_compatible_view_details : std::integral_constant<bool,
From::dimension == To::dimension &&
std::is_convertible<typename From::value_type, typename To::value_type>::value
> { };
// this is the top level one
template<typename From, typename To>
struct is_compatible_view : std::conditional_t<
is_view<From>::value && is_view<To>::value,
is_compatible_view_details<From, To>,
std::false_type>::type
{ };
不管怎样,你都需要了解细节
第三种方法是使用
enable\u if\t
作为专门化:
template <class From, class To, class = void>
struct is_compatible_view : std::false_type { };
template <class From, class To>
struct is_compatible_view<From, To, std::enable_if_t<
is_view<From>::value &&
is_view<To>::value &&
From::dimension == To::dimension &&
std::is_convertible<typename From::value_type, typename To::value_type>::value>>
: std::true_type { };
模板
结构与视图兼容:std::false\u类型{};
模板
结构是\u兼容的\u视图>
:std::true_type{};
在这里,如果
enable\u if\t
中的任何表达式格式不正确,则SFINAE将启动,我们只使用主模板,即false\u type
,实际上我没有真正理解第一个代码片段中的::type
。此外,根据用例的不同,如果兼容视图别名模板只需将From::value\u type
等中的任何错误拉到即时上下文中,则可以创建enable\u if\u compatible\u视图
别名模板。
// this one is only valid if From and To are views
template <class From, class To>
struct is_compatible_view_details : std::integral_constant<bool,
From::dimension == To::dimension &&
std::is_convertible<typename From::value_type, typename To::value_type>::value
> { };
// this is the top level one
template<typename From, typename To>
struct is_compatible_view : std::conditional_t<
is_view<From>::value && is_view<To>::value,
is_compatible_view_details<From, To>,
std::false_type>::type
{ };
template <class From, class To>
struct is_compatible_view : std::conjunction_t<
is_view<From>,
is_view<To>,
is_compatible_view_details<From, To>
>
{ };
template <class From, class To, class = void>
struct is_compatible_view : std::false_type { };
template <class From, class To>
struct is_compatible_view<From, To, std::enable_if_t<
is_view<From>::value &&
is_view<To>::value &&
From::dimension == To::dimension &&
std::is_convertible<typename From::value_type, typename To::value_type>::value>>
: std::true_type { };