【发布时间】:2012-03-28 11:35:19
【问题描述】:
我有以下代码:
typedef int AliasB;
typedef unsigned short AliasA;
class Alias
{
public:
explicit Alias(int someInt) { }
};
// (*) !! below breaks the conversion path via AliasA !!
//typedef Alias AliasA;
class C
{
public:
C() { }
};
class B
{
public:
B() { }
B(const AliasB& value) { }
operator AliasB() const
{
return -1000;
}
C combine(const B& someB)
{
return C();
}
};
class A
{
public:
A() { }
operator B() const
{
return B();
}
operator AliasA() const
{
return 1001;
// (*) !! below breaks the conversion path via AliasA !!
//return AliasA(1000);
}
A high()
{
return A();
}
A low()
{
return A();
}
C process()
{
return (static_cast<B>(low())).combine(static_cast<B>(high()));
// (**) !! the below compiles fine !!
//B theB = low();
//return theB.combine(high());
}
};
inline int someFunc(unsigned int someParam, const B& bParam)
{
return 1;
}
inline A createSomeA()
{
return A();
}
int main ()
{
A someA;
unsigned int counter = 200;
someFunc(counter, someA);
//someFunc(counter, static_cast<B>(createSomeA()));
someA.process();
return 0;
}
Clang 报如下错误:
clang_static_test.cpp:66:17: error: ambiguous conversion for static_cast from 'A' to 'B'
return (static_cast<B>(low())).combine(static_cast<B>(high()));
^~~~~~~~~~~~~~~~~~~~~
clang_static_test.cpp:21:7: note: candidate is the implicit copy constructor
class B
^
clang_static_test.cpp:25:5: note: candidate constructor
B(const AliasB& value) { }
^
clang_static_test.cpp:66:48: error: ambiguous conversion for static_cast from 'A' to 'B'
return (static_cast<B>(low())).combine(static_cast<B>(high()));
^~~~~~~~~~~~~~~~~~~~~~
clang_static_test.cpp:21:7: note: candidate is the implicit copy constructor
class B
^
clang_static_test.cpp:25:5: note: candidate constructor
B(const AliasB& value) { }
^
2 errors generated.
我无法弄清楚为什么编译器会产生错误,尽管我有 定义了转换运算符,我使用 static_cast 在该特定位置进行了显式转换。 该代码通过 GCC 4.5.2 和 Visual Studio 2008 编译器的编译。 Clang 版本是 3.1,由我自己从 Clang 和 LLVM 的 git 存储库构建 几天前。
那么,Clang 是否报告了实际错误?如果是,为什么这是一个错误,因为它是 对我来说一点都不明显(我不会问为什么其他编译器对此保持沉默)?
更新:示例代码现在是一个小的可编译示例(很抱歉从第一次没有这样做)并复制了我的真实情况。 AliasA 的转换运算符似乎是问题所在,因为如果将其删除,则一切编译正常。现在令人讨厌的是,对于上面的代码,我也从 GCC 得到错误。
UPDATE 2:我在示例中添加了一些代码以更好地反映我的真实情况;唯一的区别是,对于上面的示例,我也从 GCC 得到一个错误,而对于我的真实代码,我没有。
【问题讨论】:
-
可以出示
someFunc的声明吗? -
可能需要显示更多代码才能找出答案(最好是一个小的可编译示例)。
-
AliasB的声明是什么?
-
@R. Martinho Fernandes 添加了函数声明。
-
我发现隐式转换通常更烦人,因为它们是值得的。在这种情况下,您最好将构造函数或转换运算符设为
explicit。