2011-02-23 11 views
18

En C++ 0x, se puede crear una constexpr std :: tuple, p. Ej. comoCómo consultar un constexpr std :: tuple en tiempo de compilación?

#include <tuple> 
constexpr int i = 10; 
constexpr float f = 2.4f; 
constexpr double d = -10.4; 
constexpr std::tuple<int, float, double> tup(i, f, d); 

One también puede consultar una std :: tuple en el tiempo de ejecución, p. a través de

int i2 = std::get<0>(tup); 

Pero no es posible consultar en tiempo de compilación, por ejemplo,

constexpr int i2 = std::get<0>(tup); 

arrojará un error de compilación (al menos con la última g ++ instantánea 2011-02-19).

¿Hay alguna otra manera de consultar un constexpr std :: tuple en tiempo de compilación?

Y si no, ¿hay alguna razón conceptual por la que no se debe consultar?

(Soy consciente de evitar el uso de std :: tupla, por ejemplo, mediante el uso de impulso :: MPL o impulsar :: fusión en su lugar, pero de alguna manera suena mal en no utilizar la clase tupla en la nueva norma .. .).

Por cierto, ¿alguien sabe por qué

constexpr std::tuple<int, float, double> tup(i, f, d); 

compila bien, pero

constexpr std::tuple<int, float, double> tup(10, 2.4f, -10.4); 
no

?

¡Muchas gracias de antemano! - lars

+0

En n3225.pdf, solo el constructor predeterminado está marcado constexpr. Quizás es demasiado pronto para usar esta característica? – UncleBens

Respuesta

12

std::get no está marcado constexpr, por lo que no se puede utilizar para recuperar los valores de una tuple en un contexto constexpr, incluso si esa tupla es en sí constexpr.

Desafortunadamente, la implementación de std::tuple es opaca, por lo que tampoco puede escribir sus propios accesos.

+0

Gracias. Entonces tu respuesta es "no, no es posible". Mientras tanto, eché un vistazo a y estoy totalmente de acuerdo. Esto deja la pregunta: ¿por qué no podemos consultar std :: tuples en tiempo de compilación? Pero evtl. esta cuestión se discute mejor en el ámbito más amplio de mi [pregunta sobre constexpr of std :: forward] (http://stackoverflow.com/questions/5098069/why-discards-stdforward-constexpr-ness). – Lars

+8

[N3305] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3305.html) propone agregar constexpr para 'tuple :: get' –

-2

Todavía no he trabajado con C++ 0x, pero me parece que std :: get() es una función, en lugar de expresión que el compilador puede interpretar directamente. Como tal, no tiene ningún significado excepto en tiempo de ejecución, después de que la función misma ha sido compilada.

+1

C++ 0x agrega la palabra clave 'constexpr' que obliga al compilador a evaluar una función en tiempo de compilación, es decir, con' constexpr int add (int x, int y) {return x + y;} 'puede decir' constexpr ' int i = add (7, 13); 'y el valor de i está disponible en tiempo de compilación, por ejemplo, en' static_assert (i == 20, "i correct"); '. - Entonces mi pregunta es por qué 'std :: get' no es constexpr? – Lars

+0

La idea de 'constexpr' es que al compilador se le puede indicar que calcule el resultado de una llamada de función dado que los argumentos también son expresiones const. – UncleBens

+0

Esa no es mi lectura de las referencias que he encontrado. Mi lectura es que un constexpr puede * definir * una función en línea que devuelve una expresión constante (reemplazando macros), pero solo puede * llamar * a una función si esa función es en sí misma constexpr. –

Cuestiones relacionadas