使用运算符 T* 构造对象的 Clang 编译器错误

Clang compiler error constructing object with operator T*

本文关键字:对象 Clang 编译器 错误 运算符      更新时间:2023-10-16

我在clang(xcode(中遇到了一个奇怪的编译器问题。我只是精简了代码以突出显示问题。当我构造对象时,我单独在 clang 中出现错误,但在 msvc 中工作正常。

在下面的代码中,msvc 正确地解析了基中的运算符 T*,并在以下两种情况下使用它来构造派生运算符。但叮当机灵地只允许第二种变体。

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。但行为似乎相似。

为什么这种情况只发生在叮当声上?

我被抛弃了,因为 MSVC 用模板做了一些时髦的事情,特别是名称查找,但这实际上很容易。

这是CContainer& operator=(CContainer& p).你在那里错过了一个const,它应该是CContainer& operator=(CContainer const& p).

MSVC 还有另一个错误,它将临时引用绑定到非常量引用,如 p 。为什么这对你来说很重要?因为复制初始化IDerivedT2 spDerived = spB;涉及一个临时IDerivedT2(spB),而直接初始化IDerivedT2 spDerived(spB)不存在这种临时。