web-dev-qa-db-fra.com

Initialisation de std :: Tuple à partir de la liste des initialiseurs

Je me demande si le Tuple peut être initialisé par liste d'initialisation (pour être plus précis - par initializer_list de initializer_lists)? Considérant la définition de Tuple:

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

existe-t-il un moyen de procéder comme suit:

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

Je veux juste obtenir la même fonctionnalité que j'ai obtenue en utilisant struct au lieu de Tuple (donc seuls les tableaux sont initialisés par 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}}
};

Il n'y a aucune raison pour laquelle je dois utiliser des tuples, je me demande simplement. Je demande, car je ne peux pas passer par les erreurs de modèles g ++ qui sont générées par ma tentative d'initialisation de Tuple.

@Motti: J'ai donc raté la syntaxe appropriée pour une initialisation uniforme -

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

et

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

Mais il semble que tout le problème réside dans les tableaux, qui n'ont pas de constructeur pour initializer_list et encapsuler les tableaux avec le constructeur approprié ne semble pas si facile.

50
erjot

Les listes d'initialisation ne sont pas pertinentes pour les tuples.

Je pense que vous confondez deux utilisations différentes des accolades en C++ 0x.

  1. initializer_list<T> est une collection homogène (tous les membres doivent être du même type, donc pas pertinents pour std::Tuple)
  2. Initialisation uniforme est l'endroit où les accolades sont utilisées pour construire toutes sortes d'objets; tableaux, POD et classes avec constructeurs. Ce qui a également l'avantage de résoudre l'analyse la plus contrariante )

Voici une version simplifiée:

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

Le message d'erreur indique que vous essayez d'appeler implicitement le constructeur, mais qu'il s'agit d'un constructeur explicite, vous ne pouvez donc pas.

Fondamentalement, ce que vous essayez de faire est quelque chose comme ceci:

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