2

我有一個wrapper類來包裝std::vector<int>數據成員。我希望wrapper的構造函數將其參數轉發給vector<int>的ctor。我試圖使用可變模板構造函數來實現這一點。由於std::vector<int> v{1, 2, 3}由其std::initializer_list構造函數構造,我想wrapper激活vectorinitializer_list構造函數,當我做如何使包裝類將其構造函數參數轉發給std :: vector的構造函數?

wrapper mywrap{1, 2, 3}

但我沒有得到期望的結果:

#include <iostream> 
#include <vector> 

struct wrapper { 
    std::vector<int> v; 
    template <typename ...Tn> wrapper(Tn ...args) : v(args...) {} 
}; 

int main() { 
                  //----Output---- 
    wrapper wrap1{ 1 }; 
    std::cout << wrap1.v.size() << std::endl;    // 1 
    std::cout << wrap1.v.at(0) << std::endl;    // 0 
    wrapper wrap2{ 1, 2 }; 
    std::cout << wrap2.v.size() << std::endl;    // 1 
    std::cout << wrap2.v.at(0) << std::endl;    // 2 
    wrapper wrap3{ 1, 2, 3 };        // error 
    wrapper wrap4{ std::initializer_list<int>{ 1, 2, 3 } }; // OK 
} 

輸出顯示:

wrapper wrap1{ 1 };電話explicit vector (size_type n);

wrapper wrap2{ 1, 2 };調用

vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());

wrapper wrap3initializer_list<int>未指定時失敗。

在任何情況下,我都希望激活vectorinitializer_list<int> ctor。這怎麼解決?

+2

由於v(args ...)應該是v {args ...},所有的問題和疑問都是存在的。 – ForEveR

+0

@ForEveR讓它成爲答案! –

回答

4

它的初始化通過()和初始化{}之間的差異,在您的構造函數中,您還應該使用{}初始化。

template <typename ...Tn> wrapper(Tn ...args) : v{args...} {} 

順便說一句,如果你想只initializer_list C-TOR,何不乾脆寫這個C-TOR?

wrapper(std::initializer_list<int> args) : v(args) {} 
+1

雖然現在'wrapper(1,2)'不會像'vector(1,2)'那樣表現。 –

+0

@ForEveR謝謝,它修復了大部分代碼。但是,請你解釋一下#1a和#3嗎?如果沒有修復,不應該'包裝wrap1 {1};'由於'vector'''''''torrent無法編譯?如果沒有修復,是不是#3明確? – CodeBricks

+0

@ForEveR:正如@Mike Seymour所說,「現在'wrapper(1,2)'不會像'vector(1,2)'」那樣行事。使用你的修復,先前產生一個容器值爲1和2的元素,後者產生一個只有值爲2的元素的容器。有沒有辦法讓界面的外觀和行爲在所有情況下都完全相同?順便說一下,我瞭解使用'initializer_list' ctor,但我想了解有關參數轉發以適應所有ctors,包括我可能不知道的所有ctors(即代理模板實現可以採用所有ctors但限制其他方法'接口)。 – CodeBricks