加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在SFINAE上下文中作为模板模板参数传递的引用类型的别名模

发布时间:2020-12-16 06:03:22 所属栏目:百科 来源:网络整理
导读:我遇到G 6.1.0(-std = c 14开关)的以下问题,我不明白为什么编译器拒绝代码. 我有一个帮助结构体is_well_formed,它检查提供的模板模板参数是否形成良好的替代另一个提供的类型: templatetemplatetypename typename R,typename T,typename = voidstruct is_we
我遇到G 6.1.0(-std = c 14开关)的以下问题,我不明白为什么编译器拒绝代码.

我有一个帮助结构体is_well_formed,它检查提供的模板模板参数是否形成良好的替代另一个提供的类型:

template<template<typename> typename R,typename T,typename = void>
struct is_well_formed : std::false_type {};

template<template<typename> typename R,typename T>
struct is_well_formed<R,T,void_t<R<T>>> : std::true_type {};

我想检查一个类型是否可引用.所以我的想法是写下列内容:

// (#1)
template<class T>
using reference_t = T&;

static_assert(!is_well_formed<reference_t,void>::value,"Reference to void!?");

但是我收到一个编译错误:

main.cpp: In instantiation of 'struct is_well_formed<reference_t,double>':
main.cpp:62:51:   required from here
main.cpp:54:20: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class> class R,class T,class> struct is_well_formed'
  : std::false_type {};
                    ^
main.cpp:54:20: note:   expected a class template,got 'reference_t'
main.cpp:54:20: error: type/value mismatch at argument 1 in template parameter list for 'is_well_formed<R,<template-parameter-1-3> >::is_well_formed'
main.cpp:54:20: note:   expected a class template,got 'reference_t'

或者,以下工作与相同的static_assert:

// (#2)
template<class T>
using reference_t = void_t<T&>;

此外,以下作品,真的让我困惑:

// (#3)
template<class T>
using pointer_t = T*;

static_assert(is_well_formed<pointer_t,"No pointer to void!?");

三个别名有什么区别?是否是void_t< T&>解决方案最优雅?还是可以修改is_well_formed的helper结构来支持第一个引用版本?

编辑:我使用MSVC“15”预览4和(#1)和(#3)工作包括断言测试代码.但是当我尝试(#2)void引用的断言不起作用,即信息在替换期间丢失,并且从不选择false_type重载.哪个编译器是对的?

is_well_formed帮助器对应于SFINAE上的Stack Overflow文档页面中的can_apply结构,我刚刚删除了参数包.完整示例代码:

#include <utility>

// Only defined in std for C++17
template <class...>
using void_t = void;

// (#1) Compiler error during substitution in is_well_formed
template<class T>
using reference_t = T&;

// (#2) Ok,asserts work
/*
template<class T>
using reference_t = void_t<T&>;
*/

// (#3) Ok,asserts work
template<class T>
using pointer_t = T*;

template<template<typename> typename R,typename = void>
struct is_well_formed 
    : std::false_type {};

template<template<typename> typename R,void_t<R<T>>> 
    : std::true_type {};

int main(int,char**)
{
    static_assert(is_well_formed<reference_t,double>::value,"No reference to double!?");
    static_assert(!is_well_formed<reference_t,"Reference to void!?");

    static_assert(is_well_formed<pointer_t,"No pointer to double!?");
    static_assert(is_well_formed<pointer_t,"No pointer to void!?");

    return 0;
}

解决方法

这可能是一个编译器错误,用户 T.C.在看到这篇文章后在GCC Bugzilla here上报告.用户 Jarod42提出
template<class T>
using reference = decltype(std::declval<T&>());

作为MSVC15和GCC 6.1.0的有效替代方案.此外,他指出,MSVC仍然需要long void_t定义

template <class...>
struct make_void { using type = void; };

template <typename... T>
using void_t = typename make_void<T...>::type;

而不是明显的

template <class...>
using void_t = void;

这妨碍了原始帖子中的选项(#2)的工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读