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)
但是我尝试noexcept在noexcept规范中使用operator 来启用SFINAE失败了,模板化构造函数接受传递给它的所有内容.如何限制构造函数?
标准不允许专门化任何谓词<type_traits>.如何处理一般接受可变参数模板参数包和SFINAE的c-tors?是否存在僵局和固有的语言缺陷?
SFINAE根本不适用于异常规范,无论是否noexcept是函数类型的一部分.
请参阅[temp.deduct]/7中的注释:
替换发生在函数类型和模板参数声明中使用的所有类型和表达式中.表达式不仅包括常量表达式,例如出现在数组边界中的常量表达式,还包括非类型模板参数,还包括sizeof,decltype和允许非常量表达式的其他上下文中的通用表达式(即非常量表达式).替换以词汇顺序进行,并在遇到导致演绎失败的条件时停止.[ 注:在异常规格的等同替换完成仅在 异常规范被实例化,是形成不良的程序,此时,如果在一个无效的类型或表达所述取代得到.- 结束说明 ]
P0012R1 在这方面没有任何改变.
Piotr的答案涵盖了代码的修复.