C ++隐式转换和重载函数调用中的歧义

时间:2010-06-24 17:55:08

标签: c++ overloading implicit-conversion

我遇到了以下问题:我有一个V类(比如一个向量),我可以从中生成两个类:CI和I(想想const_iterator和iterator)。 如果我有一个const V,那么我只能生成CI(再次想到迭代器和const_iterator)。

基本上我想用(CI ci)和(V& v)替换(const V& v)和(I i)。此外,我希望能够将V obj直接传递给期望I或CI的函数,从而隐式转换从V和const V到CI和I.

我面临的问题是,当重载函数可以区分(const V& v)和(V& v)时,当我通过V obj时,它们不能“区分”(CI ci)和(I i) 。

在代码中:

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;
}

注意我可以在V中定义转换运算符(它是等价的吗?)而不是在CI和I中定义构造函数。现在:

V v;
const V cv;

fun2( v );
fun2( cv );

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

有没有办法解决这个问题而不添加任何额外的间接(即有趣的功能无法修改,而且必须直接传递给乐趣,但你可以随意修改其他内容)。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

这里需要的是显式构造函数:

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

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

太多的C ++程序员忽略了构造函数的显式关键字。默认情况下,所有一元参数化构造函数都应该是显式的。隐式构造函数会引发像这样的歧义问题,并导致非常愚蠢,迂回的转换过程,这些过程很容易导致代码问题和效率低下。

现在你已经确定,歧义问题已经解决了。如果没有显式构造函数,则无法阻止这种歧义问题。

对于客户端代码,您需要修改它以明确其转换:

V v;
const V cv;

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

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

现在需要这样的语法来构造I或CI的对象,但这是一件好事:没有人会不小心引入歧义问题。

答案 1 :(得分:0)

如何使用typedef s?

typedef V& I;
typedef const V& CI;

编辑:

没有。见评论:))