Pregunta

Estoy frente al siguiente problema: Tengo una clase V (decir un vector) de la que puede producir dos clases: CI y yo (pienso en const_iterator y iterador). Si tengo una constante V entonces sólo puedo producir CI (de nuevo pensar en iterador y const_iterator).

Esencialmente me gustaría subsitute (const V & v) con (ci CI) y (V & V) con (I i). Además me gustaría ser capaz de pasar una todavía V obj directamente a las funciones que esperan un I o una CI por lo tanto las conversiones implícitas de V y V const a CI y yo.

El problema que estoy enfrentando es que, si bien las funciones sobrecargadas pueden distinguir entre (const V & V) y (V & V), que no pueden "distinguir" entre (CI CI) y (Ii) al pasar un obj V.

En el código:

struct V {};

struct I 
{
    I( V& v ){}
};

struct CI
{
    CI( const V& v ){} //I would like to say const only 
};

void fun( I i )
{
    double x = 1.0;
}
void fun( CI ci )
{
    double x = 2.0;
}

void fun2( V& v )
{
    double x = 1.0;
}
void fun2( const V& v )
{
    double x = 2.0;
}

Aviso que podría haber definido operador conversiones en V (es equivalente?) En lugar de la definición de los constructores en CI y I. Ahora:

V v;
const V cv;

fun2( v );
fun2( cv );

fun( v ); //AMBIGUOUS!
fun( cv );

¿Hay una manera de solucionar este problema sin añadir ningún direccionamiento indirecto adicional (es decir, las funciones divertidas no pueden ser modificados y V debe ser pasada directamente a la diversión, sino que son libres de modificar todo lo demás).

Gracias de antemano por cualquier ayuda!

¿Fue útil?

Solución

Lo que se necesita aquí es constructores explícitos:

struct I 
{
    explicit I( V& v ){}
};

struct CI
{
    explicit CI( const V& v ){} //I would like to say const only 
};

Too muchos programadores de C ++ por alto la palabra clave explícita para los constructores. Todos los constructores parametrizados, unarios deben ser explícitos por defecto. constructores implícitas invitan problemas de ambigüedad como estos, así como dando lugar a muy torpe, procesos de conversión rotonda que pueden conducir fácilmente a código problemático y muy ineficiente.

Ahora usted está de problemas, la ambigüedad resuelta. Sin constructores explícitos, no se puede evitar este problema de ambigüedad.

En el código de cliente, es necesario modificarlo para ser explícito acerca de sus conversiones:

V v;
const V cv;

fun2( I(v) );
fun2( CI(cv) );

fun( I(v) );
fun( CI(cv) );

se requiere tal sintaxis ahora a los objetos de constructo de I o IC, pero eso es una cosa buena:. Nadie puede introducir accidentalmente problemas de ambigüedad más

Otros consejos

¿Qué pasa con sólo usar typedefs?

typedef V& I;
typedef const V& CI;

Editar:

No. Véanse los comentarios:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top