web-dev-qa-db-ja.com

初期化子リストからのstd :: Tupleの初期化

タプルを初期化リストで初期化できるかどうか(もっと正確に言うと、initializer_listのinitializer_listで)疑問に思っていますか?タプルの定義を考慮する:

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

Tupleの代わりにstructを使用して得たのと同じ機能を実現したいだけです(したがって、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}} };

しかし、すべての問題は配列にあり、initialize_listのコンストラクターを持たず、適切なコンストラクターで配列をラップすることはそれほど簡単ではないようです。

50
erjot

初期化子リストはタプルには関係ありません。

C++ 0xの中括弧の2つの異なる使用法を混同していると思います。

  1. initializer_list<T> は同種のコレクションです(すべてのメンバーは同じタイプでなければならないため、std::Tuple
  2. 均一な初期化 は、あらゆる種類のオブジェクトを構築するために中括弧が使用される場所です。配列、POD、およびコンストラクターを持つクラス。 最も厄介な解析 )を解決する利点もあります

簡略版は次のとおりです。

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

エラーメッセージは、コンストラクタを暗黙的に呼び出すことを試みているが、明示的なコンストラクタであるためできないことを示しています。

基本的に、あなたがやろうとしているのは次のようなものです:

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
53
Motti