簡體   English   中英

std :: initializer_list無法從中推斷出來<brace-enclosed initializer list>

[英]std::initializer_list not able to be deduced from <brace-enclosed initializer list>

我有一個類,其構造函數采用initializer_list

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

如果我嘗試直接使用大括號括起初始化列表創建對象,則會正確推導出initializer_list

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

但是,當嘗試間接執行相同操作(使用可變參數函數模板 - 在本例中為make_unique )時,編譯器無法推導出initializer_list

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

錯誤輸出:

錯誤:沒有用於調用'make_unique(<brace-enclosed initializer list>)'匹配函數

問題:

  • 為什么編譯器無法推斷{ &b }作為initializer_list<Boo*>
  • 是否可以使用我想要的語法std::make_unique<Foo>({ &b })

完整示例如下:

#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;
}

支撐的初始化程序沒有類型。 當你調用make_unique它會嘗試推斷出類型並失敗。 在這種情況下,您必須在調用時指定類型

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

這將創建一個std::initializer_list<Bar*> ,編譯器可以推導出它,並將它轉發給Foo::Foo(std::initializer_list<Bar*> bars)

原因Foo f ({ &b }); 工程是編譯器知道構造函數Foo(std::initializer_list<Bar*> bars) ,並且B* s的支撐初始化列表可以隱式轉換為std::initializer_list<Bar*> 沒有類型扣除。

make_unique使用完美轉發。

完美轉發在以下方面是不完美的:

  • 它無法轉發初始化列表

  • 它將NULL0轉換為整數,然后不能將其傳遞給指針類型的值。

  • 它不知道它的參數是什么類型,所以你不能做需要知道它們類型的操作。 舉個例子:

     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

    呼叫forwarding( {1}, {2} )不是。 它在您調用forwarding時不知道參數將是Foo ,因此它無法構造它,並且它無法通過代碼傳遞構造初始化列表(因為構造列表不是變量或表達式)。

  • 如果傳遞重載的函數名稱,則無法在調用點處計算出哪個重載。 並且一組重載不是一個值,所以你不能完美地轉發它。

  • 你無法通過位域傳遞。

  • 它強制引用其參數,即使轉發的目標沒有。 這“使用”某些靜態const數據的方式會導致程序在技術上形成錯誤。

  • 無法轉發對未知大小T(&)[]的數組的引用。 但是,您可以使用T*調用函數。

其中大約一半是從這個comp.std.c ++線程中獲取的 ,我記得有一次,我記得有其他問題我無法回想起來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM