[英]How does the second form of c++ std::make_any work?
c++ function std::make_any
有两种形式,
template< class T, class... Args >
std::any make_any( Args&&... args ); (1)
template< class T, class U, class... Args >
std::any make_any( std::initializer_list<U> il, Args&&... args ); (2)
第二种形式是如何工作的? 为什么不只是
template< class T, class U>
std::any make_any( std::initializer_list<U> il) ?
例如,在这个声明中,
std::any a = std::make_any<std::list<int>>({1,2,3}).
或者您可以将它与 initializer_list 和其他一些 arguments 一起调用,例如 {1,2,3}, 4,5? 这里的 args 是用于构造 il 还是用于列表?
第二个 for 存在的原因是由于std::initializer_list
不能很好地使用模板参数推导。 想象一下,您拥有不提供第二种形式的实现(使用std::make_any
作为实现);
template< class T, class... Args >
std::any poor_make_any(Args&&... args)
{
return std::make_any<T>(std::forward<Args>(args)...);
}
这适用于例如
struct Test {
Test(std::initializer_list<int>) {}
Test(int) {}
};
std::any x = poor_make_any<Test>(42);
但它无法编译
std::any x = poor_make_any<Test>({1, 2, 3});
再次因为std::initializer_list<int>
不能由编译器推断。 虽然您始终可以指定第二个模板参数,但这对于来自make_
系列的 function 来说过于冗长,这意味着它是一个演绎助手。
最后,剩余的 arguments 只是您免费获得的额外灵活性。 想象一下Test
示例的这个额外的构造函数,
Test(std::initializer_list<int>, int) {}
它只适用于
std::any x = std::make_any<Test>({1,2,3}, 42);
虽然如果那个可变参数的第二部分不存在,你必须
std::any x = std::make_any<Test, std::initializer_list<int>, int>({1,2,3}, 42);
这显然不是超级方便。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.