2011-01-21 8 views
23

He creado una plantilla de la siguiente manera¿Por qué no aceptar una plantilla de lista de inicialización

template<typename T> 
void f(T const& t) { } 

que quería para que esto sea exigible por contenedores, sino también por las listas de inicializador. Pensé que sería initializer_list<int>, cuando se llama de la siguiente manera.

f({1, 2, 3}); 

Pero GCC se comporta como si no los estándares de compliant

m.cpp: In function 'int main()': 
m.cpp:6:25: warning: deducing 'const T' as 'const std::initializer_list<int>' 
m.cpp:4:6: warning: in call to 'void f(const T&) [with T = std::initializer_list<int>]' 
m.cpp:6:25: warning: (you can disable this with -fno-deduce-init-list) 

¿Puede alguien explicar cómo puedo hacer este trabajo sin advertencias? ¡Gracias!

+5

Hmm parece desafortunado que SO piense que la etiqueta 'initializer_list' también está en' initializer-list' -.- C++ 0x ¡soltará lágrimas! –

+0

AFAICS, no está definido como un sinónimo en http://stackoverflow.com/tags/initializer-list/synonyms. ¿Hay alguna lógica incorporada que reemplace 'x_y' por' x-y'? – sbi

+0

Oh, no importa, acabo de ver http://meta.stackexchange.com/questions/75798/unfortunate-auto-detection-of-synonyms-for-initializer-list – sbi

Respuesta

25

Una "cosa" como {1,2,3} no califica como una expresión. No tiene ningún tipo. Por lo tanto, no se realiza ninguna deducción de tipo. Pero C++ 0x hace una excepción explícita para 'auto', por lo

auto x = {1,2,3}; 

realmente funciona y decltype (x) será initializer_list<int>. Pero esta es una regla especial que solo se aplica a automático. Supongo que querían hacer bucles como estos

for (int x : {2,3,5,7,11}) { 
    ... 
} 

funcionan porque este tipo de bucle explota la regla especial.

En cuanto a la solución del problema, habría que agregar una sobrecarga initializer_list<T> como un "contenedor":

template<class T> 
inline void outer(initializer_list<T> il) { 
    inner(il); 
} 

no he probado esto, pero mi entendimiento actual es que se debe trabajar.

+1

+1 y por ser correcto. –

+2

La regla especial mencionada está en 7.1.6.4 especificador 'auto' [dcl.spec.auto] –

+0

'C++ 0x hace una excepción explícita para 'auto'' Sí, tanto en la sintaxis similar a la asignación que mostró, y también la forma 'auto algo {a, b, c}'. Este último ha sido un dolor inconsistente en la parte posterior que ahora solo se va a solucionar con C++ 17, donde 'auto something {blah}' sin el símbolo '=' significa _'create un objeto de 'decltype (blah) ', initialised from' blah'_ - no el significado actual de _'crear una 'initializer_list' llamada' something' con un elemento del mismo tipo que 'blah''_. ¡Finalmente! Pero en este punto significa una gran cantidad de actualizaciones para las bases de código afectadas. :DO –

3

Bueno, the documentation dice que

Esta opción está presente porque esta deducción es una extensión de la especificación actual en el C++ 0x borrador de trabajo, y había cierta preocupación acerca de los posibles problemas de resolución de sobrecarga.

Esta información puede que simplemente esté desactualizada (de acuerdo con la fuente que se actualizó por última vez en 2008). Por lo que yo entiendo, la deducción se incluyó en GCC pero con la expectativa de que un borrador posterior de la norma eliminaría la regla, o al menos la limitaría.

1

¿Alguien puede explicar cómo puedo hacer que esto funcione sin advertencias?

No sé si this se refiere al código exacto que usted ha citado, o si lo que desea es saber cómo se puede crear una instancia de la plantilla de función con una lista de inicialización sin desencadenar advertencias, pero si es la última y si el problema no es más que deduciendo el tipo correcto, posiblemente podría evitarlo con sólo llamar

f<initializer_list<int>>({1, 2, 3}); 

no es bonito, pero es posible que ningún aviso y sin tocar el violín con los argumentos de línea de comandos del compilador.

Probablemente pondría un comentario cerca, lo que explica que no confíes en que el compilador deduzca el tipo correcto debido a las debilidades en ciertas versiones de GCC.

Cuestiones relacionadas