【发布时间】:2017-04-04 19:10:25
【问题描述】:
我在 clang (xcode) 中遇到了一个奇怪的编译器问题。我只是剥离了代码以突出问题。当我构造对象时,仅在 clang 中就会出现错误,但在 msvc 中可以正常工作。
在下面的代码中,msvc 正确解析了基础中的运算符 T*,并在以下两种情况下使用它来构造派生。但奇怪的是,clang 只允许第二种变体。
IDerivedT2 spDerived = spB; //错误
IDerivedT2 spDerived(spB); //工作
struct IBase { };
template <typename T>
struct CContainer
{
CContainer() {}
CContainer(T* p) {}
CContainer& operator=(T* p)
{
return *this;
}
CContainer& operator=(CContainer& p)
{
return *this;
}
operator T*()
{
return nullptr;
}
};
template <typename T>
struct CContainerDerived : public CContainer<T>
{
CContainerDerived() : CContainer<T>() {}
CContainerDerived(T* p) : CContainer<T>(p) {}
CContainerDerived(IBase* p) { *this = p; }
CContainerDerived& operator = (IBase* p)
{
return *this;
}
};
struct IDerived : public IBase { };
typedef CContainer<IBase> IBaseT1;
typedef CContainerDerived<IDerived> IDerivedT2;
int main()
{
IBaseT1 spB;
IDerivedT2 spDerived = spB; //Error
//IDerivedT2 spDerived(spB); //Works
//IDerivedT2 spDerived; //Works
//spDerived = spB;
std::cout << "Hello, world!\n";
}
http://rextester.com/VEVST22502 (clang)
http://rextester.com/ZOMDU93964 (msvc)
我的 xcode 中的 clang 编译器版本是 Apple LLVM 版本 7.3.0 (clang-703.0.29)。每个注释代码的 rextester 中的一个是 3.8。但行为似乎相似。
有什么理由单独在 clang 上发生这种情况?
【问题讨论】:
-
如果您尝试调用
CContainer& operator=(T* p),为什么不使用IDerivedT2 spDerived = &spB;,否则您传递的是T,而不是T* -
@CoryKramer:初始化,而不是赋值。
-
糟糕,我的错误,读得太快了。
-
这两种初始化方式有什么区别。到目前为止,我认为两者都是相同的,即使用适当的构造函数(如果是相同的对象,则使用复制构造函数)
-
@user3279954:见stackoverflow.com/questions/1051379/…