我在clang(xcode)中遇到一个奇怪的编译器问题。我刚刚删除了代码以突出显示问题。当我构造对象时,我单独在clang中出错,但在msvc中工作正常。
在下面的代码中,msvc正确地解析了基数中的运算符T *,并使用它来构造以下两种情况下的派生。但clang wierdly只允许第二种变体。
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(铿锵)
http://rextester.com/ZOMDU93964(msvc)
我的xcode中的clang编译器版本是Apple LLVM版本7.3.0(clang-703.0.29)。每个评论代码的rextester中的一个是3.8。但行为似乎相似。
为什么会在clang上发生这种情况?
答案 0 :(得分:2)
我被抛出是因为MSVC使用模板做了时髦的事情,特别是使用名称查找,但这实际上很容易。
这是CContainer& operator=(CContainer& p)
。你错过了const
,它应该是CContainer& operator=(CContainer const& p)
。
MSVC还有另一个错误,它会将临时对象绑定到非p
等const引用。为什么这对你来说暂时重要?因为复制初始化IDerivedT2 spDerived = spB;
涉及临时初始化IDerivedT2(spB)
不存在的临时IDerivedT2 spDerived(spB)
。