C ++对构造函数的Ambigous调用

时间:2015-05-22 08:16:52

标签: c++ constructor operator-overloading implicit-conversion explicit

我有一个包含多个构造函数和重载运算符的类:

class Utf8String
{
public:

   Utf8String();

   explicit Utf8String( const char * sStr );

   Utf8String( const char * sStrBeg, const char * sStrEnd );

   Utf8String( const char * sStr, uint32_t nCpCount );

   explicit Utf8String( const Utf8String & sStr );

   explicit Utf8String( const Utf8String & sStr, uint32_t nStart = 0, uint32_t nCpCount = UINT32_MAX );

   Utf8String( uint32_t nCpCount, uchar32_t cCodePoint );

   explicit Utf8String( long int iVal );

   explicit Utf8String( double fVal );

   // More stuff

   inline Utf8String operator + ( const char * sStr ) const
   {
      Utf8String sRes( *this ); // ERROR
      return sRes += sStr;
   }

   inline operator const char * () const;

   inline operator char * ();

   inline operator long int () const;

   inline operator double () const;
};

出于某种原因,我收到了错误:

Error   3   error C2668: 'core::Utf8String::Utf8String' : ambiguous call to overloaded function c:\xxx\utf8string.h 280

我尝试添加明确的关键字,似乎有意义。我还明确地向所有构造函数添加了内容,只是为了看看会发生什么,但无论我做什么我都会收到此错误并且可以'找出原因。

你知道吗?谢谢。

2 个答案:

答案 0 :(得分:3)

这两个功能:

explicit Utf8String( const Utf8String & sStr );

explicit Utf8String( const Utf8String & sStr, uint32_t nStart = 0, uint32_t nCpCount = UINT32_MAX );

不应该同时存在。他们引发了这个问题。

由于第二个构造函数的其余参数具有默认值,如果只传递一个参数,它们将导致模糊错误,如下所示:

 Utf8String s = get_utfString();

 Utf8String s1(s); //which above constructor should be called?

一个修复方法是:删除第二个构造函数的默认值。

此外,这些构造函数是复制构造函数,因此explicit没有多大意义。您可以使用explicit来避免隐式版本从一种类型X转移到另一种类型Y。在这种情况下,避免从Utf8String const&Utf8String的隐式转换没有意义,因为这样的转换不会导致问题(如果确实如此,那么问题很可能是在你的代码的其他部分)。

答案 1 :(得分:1)

以下两个构造函数都可以用作复制构造函数:

explicit Utf8String( const Utf8String & sStr );
explicit Utf8String( const Utf8String & sStr, uint32_t nStart = 0, uint32_t nCpCount = UINT32_MAX );

每个匹配Utf8String( const Utf8String & sStr )签名。这是编译器不喜欢的。

您应该考虑将两个构造函数中的哪一个用作复制构造函数。如果是第一个,则在第二个构造函数中删除nStart的默认值。如果它是第二个,那么完全删除第一个构造函数。

实际上,我假设您的第二个构造函数只接受一个子字符串,因此在没有nStartnCpCount参数的情况下调用将完全像复制构造函数一样工作。所以最简单的方法就是删除这对中的第一个构造函数。

但是,这可能会导致一些(主要是性能)问题,具体取决于您对Utf8String的表示,因此由您决定。