std::initializer_list not able to be deduced from

前端 未结 2 2013
我寻月下人不归
我寻月下人不归 2021-01-20 01:05

I have a class whose constructor takes an initializer_list:

Foo::Foo(std::initializer_list bars)

If I attempt to c

相关标签:
2条回答
  • 2021-01-20 01:39

    A braced initializer has no type. When you call make_unique it tries to deduce the type and fails. In this case you have to specify the type when calling like

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

    This will create a std::initializer_list<Bar*> which the compiler can deduce and it will forward it to Foo::Foo(std::initializer_list<Bar*> bars)

    The reason Foo f ({ &b }); works is that the compiler knows of the constructor Foo(std::initializer_list<Bar*> bars) and braced initializer list of B*s can be implicitly converted to a std::initializer_list<Bar*>. There is not type deduction going on.

    0 讨论(0)
  • 2021-01-20 01:47

    make_unique uses perfect forwarding.

    Perfect forwarding is imperfect in the following ways:

    • It fails to forward initializer lists

    • 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)...);
      }
      

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

      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.

    • You cannot pass bitfields 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.

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

    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.

    0 讨论(0)
提交回复
热议问题