std :: initializer_list无法从<括号括起始化器列表>中推导出来。 [英] std::initializer_list not able to be deduced from <brace-enclosed initializer list>

查看:1086
本文介绍了std :: initializer_list无法从<括号括起始化器列表>中推导出来。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类的构造函数需要 initializer_list

I have a class whose constructor takes an initializer_list:

Foo::Foo(std::initializer_list<Bar*> bars)

直接的对象, initializer_list 可以正确推导出来:

If I attempt to create an object with a brace-enclosed initializer list directly, the initializer_list is correctly deduced:

Foo f ({ &b }); // std::initializer_list<Bar*> correctly deduced

但是,当试图做同样间接变量函数模板 - 在这种情况下 make_unique ),编译器无法推导出 initializer_list

However, when trying to do the same indirectly (with a variadic function template - in this case make_unique), the compiler is unable to deduce the initializer_list:

std::make_unique<Foo>({ &b }); // std::initializer_list<Bar*> not deduced

错误输出


错误:没有匹配的函数调用'make_unique(<括号括起始化列表>)'

问题:


  • 为什么编译器无法将 {& b} 推导为 initializer_list< Boo *> li>
  • 是否可以使用我想要的语法 std :: make_unique< Foo>({& b}) >
  • Why is the compiler failing to deduce { &b } as a initializer_list<Boo*>?
  • Is it possible to use the syntax std::make_unique<Foo>({ &b }) which I desire?

完整示例如下:

#include <initializer_list>
#include <memory>

struct Bar
{};

struct Foo
{
    Foo(std::initializer_list<Bar*> bars)
    { }
};

int main()
{
    Bar b;

    // initializer_list able to be deduced from { &b }
    Foo f ({ &b });

    // initializer_list not able to be deduced from { &b }
    std::unique_ptr<Foo> p = std::make_unique<Foo>({ &b });

    (void)f;
    return 0;
}


推荐答案

完美转发在以下方面不完美:

Perfect forwarding is imperfect in the following ways:


  • 它无法转发初始值列表

  • It fails to forward initializer lists

它转换 NULL 0 为一个整数,然后无法传递到指针类型的值。

It converts NULL or 0 to an integer, which can then not be passed to a value of pointer type.

它不知道它的参数将是什么类型,所以你不能做需要知道他们的类型的操作。例如:

It does not know what type its arguments will be, so you cannot do operations that require knowing their type. As an example:

struct Foo { int x; };
void some_funcion( Foo, Foo ) {};

template<class...Args>
decltype(auto) forwarding( Args&& ... args ) {
  return some_function(std::forward<Args>(args)...);
}

调用 some_function({1},{2} )是合法的。它用 {1} {2} Foo c>。

Calling some_function( {1}, {2} ) is legal. It constructs the Foos with {1} and {2}.

调用转发({1},{2})它不知道在你调用转发的时候,参数将是 Foo s,因此它不能构造它,并且它不能通过代码传递构造初始化列表(因为构造列表不是变量或表达式)。

Calling forwarding( {1}, {2} ) is not. It does not know at the time you call forwarding that the arguments will be Foos, so it cannot construct it, and it cannot pass the construction-initializer-list through the code (as construction-lists are not variables or expressions).

如果传递一个重载的函数名,这种过载不能在呼叫点处计算出来。

If you pass an overloaded function name, which overload cannot be worked out at the point of call. And a set of overloads is not a value, so you cannot perfect forward it through.

不能通过位字段。

它强制引用它的参数,即使转发的目标没有。

It forces takes a reference to its arguments, even if the forwarded target does not. This "uses" some static const data in ways that can cause a program to be technically ill-formed.

引用未知大小的数组 T(&)[] 无法转发。

A reference to an array of unknown size T(&)[] cannot be forwarded. You can call a function taking a T* with it, however.

其中大约一半来自这个comp.std.c ++线程,我一次想起来,我记得还有其他问题,我不记得我的头顶。

About half of these were taken from this comp.std.c++ thread, which I looked for once I remembered there were other issues I couldn't recall off the top of my head.

这篇关于std :: initializer_list无法从&lt;括号括起始化器列表&gt;中推导出来。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆