2010-08-05 198 views
38

我想知道元組是否可以通過初始化列表進行初始化(更確切地說 - initializer_list的initializer_list)?考慮到元組的定義:初始化從初始化列表中的std ::元組

typedef std::tuple< std::array<short, 3>, 
        std::array<float, 2>, 
        std::array<unsigned char, 4>, 
        std::array<unsigned char, 4> > vertex; 

有以下這樣做的任何方式:

static vertex const nullvertex = { {{0, 0, 0}}, 
            {{0.0, 0.0}}, 
            {{0, 0, 0, 0}}, 
            {{0, 0, 0, 0}} }; 

我只是想實現我使用結構,而不是元組相同的功能(因此只陣列由initializer_list初始化):

static struct vertex { 
    std::array<short, 3> m_vertex_coords; 
    std::array<float, 2> m_texture_coords; 
    std::array<unsigned char, 4> m_color_1; 
    std::array<unsigned char, 4> m_color_2; 
} const nullvertex = { 
    {{0, 0, 0}}, 
    {{0.0, 0.0}}, 
    {{0, 0, 0, 0}}, 
    {{0, 0, 0, 0}} 
}; 

沒有理由我必須使用元組,只是想知道。我問,因爲我無法通過由我嘗試這種元組初始化生成的g ++模板錯誤。

@Motti:所以我錯過了統一初始化的正確語法 -

static vertex const nullvertex = vertex{ {{0, 0, 0}}, 
             {{0.0, 0.0}}, 
             {{0, 0, 0, 0}}, 
             {{0, 0, 0, 0}} }; 

static vertex const nullvertex{ {{0, 0, 0}}, 
           {{0.0, 0.0}}, 
           {{0, 0, 0, 0}}, 
           {{0, 0, 0, 0}} }; 

但似乎所有的麻煩在於陣列,其中有沒有構造函數initializer_list和用合適的構造函數包裝數組似乎不是那麼容易的任務。

回答

40

初始化列表與元組無關。

我認爲你在C++ 0x中混淆了花括號的兩種不同用法。

  1. initializer_list<T>是均勻的集合(所有成員必須是同一類型的,所以不適合std::tuple相關)
  2. Uniform initialization是其中大括號,以便構建各種對象的使用;數組,POD和具有構造函數的類。其中也有解決the most vexing parse的利益)

下面是一個簡化版本:

std::tuple<int, char> t = { 1, '1' }; 
// error: converting to 'std::tuple<int, char>' from initializer list would use 
// explicit constructor 'std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) 
// [with _U1 = int, _U2 = char, _T1 = int, _T2 = char]' 

std::tuple<int, char> t { 1, '1' }; // note no assignment 
// OK, but not an initializer list, uniform initialization 

錯誤消息說的是,你試圖隱含調用構造函數,但它是一個明確的構造函數,因此你可以「T。

基本上你想要做的是這樣的:

struct A { 
    explicit A(int) {} 
}; 

A a0 = 3; 
// Error: conversion from 'int' to non-scalar type 'A' requested 

A a1 = {3}; 
// Error: converting to 'const A' from initializer list would use 
// explicit constructor 'A::A(int)' 

A a2(3); // OK C++98 style 
A a3{3}; // OK C++0x Uniform initialization 
+0

感謝您的答覆! – erjot 2010-08-06 09:06:58

+5

爲什麼用一個加載的init列表構造一個'std :: tuple'是一件壞事?它適用於'std :: pair's,'std :: tuple'是'std :: pair'的泛化,所以我不明白這個限制的原因:S ... – rubenvb 2012-08-28 19:36:02

+4

@rubenvb可以用統一的初始化(大括號)初始化一個'元組',但要做到這一點,你必須刪除等號。如果你有一個等號,這意味着你使用一個參數構造函數構造一個臨時接受一個初始化列表,然後從臨時值中使用複製構造函數(儘管編譯器可以省略其中的一部分)。 – Motti 2012-08-29 07:50:22