SFINAE和noexcept指定符 [英] SFINAE and noexcept specifier

查看:85
本文介绍了SFINAE和noexcept指定符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在函数模板的重载解析期间, noexcept 说明符的括号中是否包含SFINAE?



我要为聚集体做一个包装,并希望 std :: is_constructible 谓词对其正确起作用:

 模板<类型名称类型> 
结构拥抱
:键入
{

template<类型名...参数>
拥抱(参数&& ... _arguments)noexcept(noexcept(type {std :: forward< arguments>(_ arguments)...})))
:type {std :: forward< ; arguments>(_ arguments)...} //花括号
{; }

};

int
main()
{
struct S {int i;双j; }; //使用E =拥抱<汇总
S>
E b(1,1.0); //括号-可构造=>可以用作常规类型
b.i = 1; b.j = 2.0; //可访问
static_assert(std :: is_constructible< E,int,double> {});
static_assert(std :: is_constructible< E,结构B> {}); //要在此处出现严重错误
返回EXIT_SUCCESS;
}

但是我尝试使用 noexcept noexcept 规范内的$ c>运算符启用SFINAE失败,并且模板化构造函数接受传递给它的所有内容。如何限制构造函数?



标准不允许对< type_traits> 。一般情况下,如何处理接受可变参数模板参数包和SFINAE的c-tor?有僵局和固有的语言缺陷吗?

解决方案

SFINAE根本不适用于例外规范 s,是否 noexcept 是函数类型的一部分。



请参见[temp.deduct ] / 7:


替换发生在
函数类型和模板参数声明中使用的所有类型和表达式中。
表达式不仅包括常量表达式(如
出现在数组范围内或作为非类型模板参数的常量表达式),还包括sizeof,$ b $内的
通用表达式(即非恒定表达式) b十进制类型,以及其他允许非恒定表达式的上下文。
替换以词法顺序进行,并在遇到
导致推论失败的条件时停止。 [ Note :仅当实例化
exception-specification 时,才在异常规范中进行等效的
替换,这时程序将如果替换导致无效类型或
表达式,则形成此格式。 — 尾注]


P0012R1 在这方面没有任何改变



Piotr的答案涵盖了代码的修复方法。 / p>

Does an expression in noexcept specifier's parentheses participate in SFINAE during overload resolution of function templates?

I want to make an wrapper for aggregates and want the std::is_constructible predicate to work properly for it:

template< typename type >
struct embrace
    : type
{

    template< typename ...arguments >
    embrace(arguments &&... _arguments) noexcept(noexcept(type{std::forward< arguments >(_arguments)...}))
        : type{std::forward< arguments >(_arguments)...} // braces 
    { ; }

};

int
main()
{
    struct S { int i; double j; }; // aggregate
    using E = embrace< S >;
    E b(1, 1.0); // "parentheses"-constructible => can be used as usual types
    b.i = 1; b.j = 2.0; // accessible
    static_assert(std::is_constructible< E, int, double >{});
    static_assert(std::is_constructible< E, struct B >{}); // want hard error here
    return EXIT_SUCCESS;
}

But my attempt to use noexcept operator inside noexcept specification to enable SFINAE is failed, and the templated constructor accepts everything passed to it. How can the constructor be restricted?

It is not permitted by the Standard to specialize any predicates from <type_traits>. How to deal with c-tors that accepts variadic template parameter packs and SFINAE in general? Is there an impasse and inherent language flaw?

解决方案

SFINAE simply doesn't apply to exception-specifications, whether or not noexcept is part of the function type.

See the note in [temp.deduct]/7:

The substitution occurs in all types and expressions that are used in the function type and in template parameter declarations. The expressions include not only constant expressions such as those that appear in array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions) inside sizeof, decltype, and other contexts that allow non-constant expressions. The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered. [ Note: The equivalent substitution in exception specifications is done only when the exception-specification is instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression. —end note ]

P0012R1 didn't change anything in this respect.

Piotr's answer covers the fix for your code.

这篇关于SFINAE和noexcept指定符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆