简体   繁体   English

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

[英]How does the second form of c++ std::make_any work?

There are two form of the c++ function std::make_any , 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)

How does the second form work?第二种形式是如何工作的? Why it is not just为什么不只是

template< class T, class U>
std::any make_any( std::initializer_list<U> il) ?

For example, in this statement,例如,在这个声明中,

std::any a = std::make_any<std::list<int>>({1,2,3}).

Or can you call it with both an initializer_list and together with some other arguments, such as, {1,2,3}, 4,5?或者您可以将它与 initializer_list 和其他一些 arguments 一起调用,例如 {1,2,3}, 4,5? Is the args here for constructing il, or for list?这里的 args 是用于构造 il 还是用于列表?

The reason this second for exists is due to std::initializer_list not playing well with template argument deduction.第二个 for 存在的原因是由于std::initializer_list不能很好地使用模板参数推导。 Imagine you own implementation (using std::make_any as an implementation) that does not offer the second form;想象一下,您拥有提供第二种形式的实现(使用std::make_any作为实现);

template< class T, class... Args >
std::any poor_make_any(Args&&... args)
{
    return std::make_any<T>(std::forward<Args>(args)...);
}

This works well for eg这适用于例如

struct Test {
    Test(std::initializer_list<int>) {}
    Test(int) {}
};

std::any x = poor_make_any<Test>(42);

but it fails to compile for但它无法编译

std::any x = poor_make_any<Test>({1, 2, 3});

again because std::initializer_list<int> cannot be deduced by the compiler.再次因为std::initializer_list<int>不能由编译器推断。 While you can always specify the second template argument, this is overly verbose for a function from the make_ family that is meant to be a deduction helper.虽然您始终可以指定第二个模板参数,但这对于来自make_系列的 function 来说过于冗长,这意味着它是一个演绎助手。

And finally, the remaining arguments are just additional flexibility that you get for free.最后,剩余的 arguments 只是您免费获得的额外灵活性。 Imagine this additional constructor for the Test example,想象一下Test示例的这个额外的构造函数,

Test(std::initializer_list<int>, int) {}

It just works with它只适用于

std::any x = std::make_any<Test>({1,2,3}, 42);

While if that variadic second part wasn't there, you had to虽然如果那个可变参数的第二部分不存在,你必须

std::any x = std::make_any<Test, std::initializer_list<int>, int>({1,2,3}, 42);

which is obviously not super convenient.这显然不是超级方便。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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