繁体   English   中英

c++ std::make_any 的第二种形式如何工作?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM