2010-08-05 8 views
38

Je me demande si le tuple peut être initialisé par la liste d'initialisation (pour être plus précis - par initializer_list de initializer_lists)? Compte tenu de la définition de tuple:Initialisation de std :: tuple à partir de la liste d'initialisation

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

est-il possible de faire ce qui suit:

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

Je veux juste obtenir même fonctionnalité que je suis arrivé à l'aide struct au lieu de tuple (sont initialisés tableaux ainsi que 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 demandais simplement. Je demande, parce que je suis incapable de passer par des erreurs g ++ modèles qui sont générés par ma tentative d'une telle initialisation de tuple.

@Motti: Je manqué la syntaxe correcte pour l'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 ont obtenu aucun constructeur pour initializer_list et Envelopper les tableaux avec un constructeur approprié ne semble pas si facile.

Répondre

40

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 pertinentes pour std::tuple)
  2. Uniform initialization est l'endroit où les accolades sont utilisées pour construire toutes sortes d'objets; tableaux, POD et classes avec des constructeurs. Ce qui a aussi l'avantage de résoudre the most vexing parse)

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 est que vous essayez d'appeler implicitement le constructeur, mais il est un constructeur explicite afin que vous puissiez 't.

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 
+0

Merci pour la réponse! – erjot

+5

Pourquoi la construction d'un 'std :: tuple' avec une liste init braced est-elle une mauvaise chose? Cela fonctionne pour 'std :: pair's, et un' std :: tuple' est la généralisation de 'std :: pair', donc je ne comprends pas la raison de cette limitation: S ... – rubenvb

+4

@rubenvb il est possible d'initialiser un 'tuple' avec une initialisation uniforme (accolades) mais pour ce faire, vous devez supprimer le signe égal. Si vous avez un signe égal, cela signifie que vous construisez un temporaire avec le constructeur à un paramètre acceptant une liste d'initialisation, puis utilisez le constructeur de copie à partir de la valeur temporaire (bien que le compilateur puisse en éluder une partie). – Motti

Questions connexes