我有2个非常简单的类,ClassA和ClassB.我希望能够从ClassB转换为ClassA.使用Sun C++ 5.11,它可以很好地编译并按照我的预期运行,根据这个:转换构造函数与转换运算符:优先级.
当我尝试使用gcc版本4.8.2编译它时,它给出了一个关于对重载函数的模糊调用的错误.当铸造看起来是一个相当明确的行为时,为什么这会表现不同?
守则:
main.cc
#include <iostream>
class ClassB;
class ClassA
{
public:
ClassA( const int& num )
: _number( num )
{ std::cout << "ClassA int constructor\n"; }
private:
int _number;
};
class ClassB
{
public:
ClassB( const int& num )
: _number( num )
{ std::cout << "ClassB int constructor\n"; }
operator ClassA() const throw()
{
std::cout << "ClassB operator ClassA()\n";
return ClassA( _number );
}
operator int() const throw()
{
std::cout << "ClassB operator int()\n";
return _number;
}
private:
int _number;
};
int main( int argc, const char* argv[] )
{
std::cout << "Creating b:\n";
ClassB b( 5 );
std::cout << "Casting b to a ClassA:\n";
ClassA a = static_cast<ClassA>( b );
}
Run Code Online (Sandbox Code Playgroud)
使用Sun C++ 5.11,它可以很好地编译并吐出以下输出:
Creating b:
ClassB int constructor
Casting b to a ClassA:
ClassB operator ClassA()
ClassA int constructor
Run Code Online (Sandbox Code Playgroud)
使用gcc,编译器会发出以下错误:
main.cc: In function 'int main(int, const char**)':
main.cc:43:36: error: call of overloaded 'ClassA(ClassB&)' is ambiguous
ClassA a = static_cast<ClassA>( b );
^
main.cc:43:36: note: candidates are:
main.cc:8:2: note: ClassA::ClassA(const int&)
ClassA( const int& num )
^
main.cc:5:7: note: ClassA::ClassA(const ClassA&)
class ClassA
Run Code Online (Sandbox Code Playgroud)
如果我注释掉ClassB :: operator int()或ClassA :: ClassA(const int&),它会很好地编译并提供相同的输出.如果我注释掉ClassB :: operator CLassA(),我得到以下输出:
Creating b:
ClassB int constructor
Casting b to a ClassA:
ClassB operator int()
ClassA int constructor
Run Code Online (Sandbox Code Playgroud)
为什么gcc认为这两个转换序列是等价的:
ClassB :: operator ClassA()
ClassB :: operator int() - > ClassA :: ClassA(const int&)
如果您的编译器支持 C++11 功能,您可以显式声明转换运算符:
class ClassB
{
public:
explicit ClassB( const int& num );
explicit operator ClassA() const throw();
explicit operator int() const throw();
explicit operator float() const throw();
int getNumber() const;
private:
int _number;
}
Run Code Online (Sandbox Code Playgroud)
因此,编译器不会在重载决策中与
static_cast<>由于隐式转换而必须进行选择的不明确调用相混淆。
| 归档时间: |
|
| 查看次数: |
746 次 |
| 最近记录: |