2012-03-28 17 views
5

estoy tratando de escribir operador booleano conversión para std :: bitsetsobrecarga de conversión no miembros a bool operador

Traté:

template<size_t size> 
operator bool(std::bitset<size> & b) 
{ 
    return b.any(); 
} 

pero tengo

error C2801: 'mynamespace::operator bool' must be a non-static member 

de mi visual-studio.

Pero cuando miro hacia arriba C2801 explanation no dice nada sobre los operadores de conversión (sólo alrededor =, ->, [],())

Por lo tanto, es posible la escritura de alguna manera "std :: Conversión bitset a bool ¿operador?"

(no puedo llamar a mi b.any() en las sentencias if, debido a que el mismo código debe ejecutarse cuando std :: bitset se reemplaza con sin firmar o algo

typedef std::bitset<x> Bitset; 
//typedef unsigned Bitset; 

lo que la sintaxis ideal será como:

Bitset b = whatewer; 
if(b) 
    doStuff(); 

)

Si esta sobrecarga no es posible, ¿cuál es la solución recomendada?

hasta ahora lo uso como:

if(b == Bitset(0)) 
    doStuff(); 

pero no me gusta él.

Gracias

+0

Esta es una pregunta interesante. No conozco ninguna forma directa de hacer lo que sugieres. Puede que no exista uno. Como saben, el problema es que ni el tipo convertido ni el tipo convertido es definido por el usuario. El compilador no quiere permitirle agregar nuevas conversiones de implícita entre tipos que no creó. Puede que tenga que definir y llamar explícitamente su propia función * make_bool(). * Al menos si * en línea * su función, debe ser tan eficiente en tiempo de ejecución como una conversión incorporada; pero no obtendrás una conversión implícita, ¿o sí? – thb

Respuesta

6

Como dice el mensaje de error, el operador de conversión debe ser no estático miembro de una clase . Eso es verdad.

No puedo llamar a b.any() en mis sentencias if, porque el mismo código debe ejecutarse cuando std :: bitset se reemplaza por unsigned o algo.

Si ese es su problema, entonces usted puede utilizar la sobrecarga de la función, y la llama que pasa el argumento de que devolverá un valor booleano:

template<typename T> 
bool to_bool(T const & b) 
{ 
    return b; //implicit conversion (if allowed) for all other types 
} 

template<size_t N> 
bool to_bool(std::bitset<N> const & b) 
{ 
    return b.any(); 
} 

luego usarlo como:

if (to_bool(whatever)) 
{ 
} 

Llamará a la sobrecarga correcta. Si el tipo de whatever es std::bitset<N>, se llamará a la segunda función sobrecargada, de lo contrario se llamará a la primera.

+1

Intenté hacer esto con especialización cuando todo lo que necesitaba era sobrecarga. Esto parece estar bien. –

+0

@MarkB: Sí, vi que estaba haciendo una especialización parcial de la plantilla de función que no está permitida. – Nawaz

+2

@Nawaz muchas gracias, esta es la mejor solución. Incluso puedo llamarlo como 'if ((to_bool) (whatever))' para obtener más impresión de casting :) gracias una vez más – relaxxx

5

§12.3.2/1: "Un miembro función de una clase X con un nombre de la forma [...] especifica una conversión de X al tipo especificado ..." (C++ 11 usa el mismo número de sección y casi la misma redacción, agregando solo que la función no toma parámetros).

La otra forma posible de definir una conversión es un constructor (§12.3.1), que obviamente también es un miembro de la clase.

En resumen, sí, las conversiones siempre se deben definir como funciones de miembro.

Una manera de hacer lo que quiera sería escribir una envoltura alrededor de std::bitset que proporciona la conversión se preocupan por:

template <int size> 
class mybitest { 
    std::bitset<size> bits; 
public: 
    operator bool() { return bits.any(); } 
} 

Pero si decide hacerlo, tendrá que escribir funciones de envío para prácticamente todas las piezas de bitset que está usando (ctors, asignación, etc.)

+0

Gracias, su respuesta es definitivamente correcta, pero iré con la solución de Nawaz. Su solución es "mucho trabajo" pero me dará la sintaxis que quería. Una vez mas, Gracias – relaxxx

2

El estándar es un poco claro en este (12.3.2):

Una función miembro de una clase X que no tiene parámetros con un nombre del formulario [...] especifica una conversión de X al tipo especificado por la conversión-tipo-id. Tales funciones se llaman funciones de conversión. No se puede especificar ningún tipo de devolución. Si una función de conversión es una función miembro, el tipo de la función de conversión (8.3.5) es "función que no toma ningún parámetro que devuelva conversion-type-id".

La primera frase parece implicar que sólo funciones miembro pueden ser funciones de conversión, pero no estoy seguro de cuál es el propósito de la condicional "si una función de conversión es una función miembro" es.

Tomaría la primera oración como vinculante y concluiría que una función de conversión debe ser una función miembro.