首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重载函数调用中的C++隐式转换和歧义

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

Stack Overflow用户
提问于 2010-06-25 01:55:08
回答 2查看 2K关注 0票数 4

我面临着以下问题:我有一个V类(比如一个向量),我可以从中产生两个类: CI和I(想想const_iterator和迭代器)。如果我有一个常量V,那么我只能产生CI (再想想迭代器和const_iterator)。

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

我面临的问题是,虽然重载函数可以区分(const V& v)和(V& v),但当我传递一个V obj时,它们不能区分(CI ci)和(I i)。

在代码中:

代码语言:javascript
运行
复制
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中定义构造函数。现在:

代码语言:javascript
运行
复制
V v;
const V cv;

fun2( v );
fun2( cv );

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

有没有办法解决这个问题而不增加任何额外的间接性(例如,fun函数不能被修改,v必须直接传递给fun,但你可以自由地修改其他所有东西)。

提前感谢您的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-06-25 09:51:12

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

代码语言:javascript
运行
复制
struct I 
{
    explicit I( V& v ){}
};

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

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

现在你设置好了,歧义问题就解决了。如果没有显式的构造函数,就无法防止这种多义性问题。

对于客户端代码,您确实需要将其修改为显式地表示其转换:

代码语言:javascript
运行
复制
V v;
const V cv;

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

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

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

票数 4
EN

Stack Overflow用户

发布于 2010-06-25 02:03:48

如果只使用typedefs呢?

代码语言:javascript
运行
复制
typedef V& I;
typedef const V& CI;

编辑:

不是的。请参阅评论:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3112602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档