2011-02-07 14 views
13

¿Cómo puedo evitar la compilación de la última línea de este código?Conversión de impulso :: opcional a bool

#include <boost/optional.hpp> 

int main() 
{ 
    typedef boost::optional<int> int_opt; 
    int_opt opt = 0; 
    bool x = opt; // <- I do not want this to compile 
} 

La última línea no examina opt 's contenían valor int, pero en su lugar se compila como un tipo de conversión a bool, y no parece ser lo que el usuario pretende.

La fraseología bool segura parece ser relevante aquí?

+4

¿Qué quieres decir con algo así? Describe en inglés lo que quieres. El código obviamente no describe lo que quieres. Entonces, ¿cómo deberíamos saber? – Oswald

+1

no se puede, 'boost :: optional' implementa' operator! 'Y esta es la razón por la cual la última línea arriba compila. Ni siquiera puede derivar de esto para ocultar ese operador; necesita reparar su código. – Nim

Respuesta

16

El punto de boost::optional es permitir código como este:

void func(boost::optional<int> optionalArg) 
{ 
    if (optionalArg) { 
     doSomething(*optionalArg); 
    } 
} 

Así que la conversión implícita a bool es una característica y no se debería impedir la compilación.

+0

¿Esto no es lo que la expresión idiomática segura intenta resolver? (http://www.artima.com/cppsource/safebool.html) – dimba

+3

@dimba: la expresión de bool naturalmente segura no evita el uso del valor en contextos puramente booleanos. – UncleBens

+0

@UncleBens - de hecho, cambiando el tipo x en la última línea de bool a int causas a error de compilación. – dimba

1

Si está usando optional, debe poder determinar si está configurado antes de usarlo. La forma en que esto se implementa es con la conversión (efectivamente bool).

No tengo en mente que el usuario no quiere lo que realmente está escrito allí: deben saber que es optional y que lo están verificando para verificar su validez.

Como la conversión está integrada en boost::optional, no tengo conocimiento de ninguna forma de eliminarla directamente.

Podría, por supuesto, implementar una clase contenedora para su necesidad particular de int que proporcione solo las partes de la interfaz optional que desee, posiblemente con una función explícita que verifique la validez.

Alternativamente, siempre se puede usar template<class T> inline T const* get_pointer (optional<T> const& opt) ; o su versión no const cuando se trabaja con optional s para que sea explícito lo que está sucediendo.

1

El problema que describe solía ser el caso de las versiones anteriores de Boost. Desde la versión 1.56, boost::optional tiene una conversión explícita a bool y el código que muestra ya no compila (exactamente de la manera que quería). See here.

Cuestiones relacionadas