SFINAE和noexcept说明符

Ori*_*ent 9 c++ constructor sfinae c++11 c++14

noexcept函数模板的重载解析期间,说明符括号中的表达式是否参与SFINAE?

我想为聚合创建一个包装器,并希望std::is_constructible谓词正常工作:

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;
}
Run Code Online (Sandbox Code Playgroud)

但是我尝试noexceptnoexcept规范中使用operator 来启用SFINAE失败了,模板化构造函数接受传递给它的所有内容.如何限制构造函数?

标准不允许专门化任何谓词<type_traits>.如何处理一般接受可变参数模板参数包和SFINAE的c-tors?是否存在僵局和固有的语言缺陷?

T.C*_*.C. 6

SFINAE根本不适用于异常规范,无论是否noexcept是函数类型的一部分.

请参阅[temp.deduct]/7中的注释:

替换发生在函数类型和模板参数声明中使用的所有类型和表达式中.表达式不仅包括常量表达式,例如出现在数组边界中的常量表达式,还包括非类型模板参数,还包括sizeof,decltype和允许非常量表达式的其他上下文中的通用表达式(即非常量表达式).替换以词汇顺序进行,并在遇到导致演绎失败的条件时停止.[ :在异常规格的等同替换完成仅在 异常规范被实例化,是形成不良的程序,此时,如果在一个无效的类型或表达所述取代得到.- 结束说明 ]

P0012R1 在这方面没有任何改变.

Piotr的答案涵盖了代码的修复.

  • @Orient P0012R1是"添加类型系统的异常规范"论文,并且在异常规范中没有改变任何与r/t SFINAE相关的内容.现在说,当我们还有两年之后,C++ 17将不会做X,这为时过早. (2认同)