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

时间:2017-04-04 19:10:25

标签: c++ xcode clang

我在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上发生这种情况?

1 个答案:

答案 0 :(得分:2)

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

这是CContainer& operator=(CContainer& p)。你错过了const,它应该是CContainer& operator=(CContainer const& p)

MSVC还有另一个错误,它会将临​​时对象绑定到非p等const引用。为什么这对你来说暂时重要?因为复制初始化IDerivedT2 spDerived = spB;涉及临时初始化IDerivedT2(spB)不存在的临时IDerivedT2 spDerived(spB)