我想为聚合创建一个包装器,并希望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; }
但是我尝试在noexcept规范中使用noexcept操作符来启用SFINAE失败,并且模板构造函数接受传递给它的所有内容.构造函数如何被限制?
标准不允许专门从< type_traits> ;.的任何谓词.如何处理接受可变模板参数包和SFINAE的转换器?是否有僵局和固有的语言缺陷?
解决方法
见[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在这方面.
Piotr的答案涵盖了您的代码的修复.