【问题标题】:Clang compiler error constructing object with operator T*Clang 编译器错误使用运算符 T* 构造对象
【发布时间】: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&amp; operator=(T* p),为什么不使用IDerivedT2 spDerived = &amp;spB;,否则您传递的是T,而不是T*
  • @CoryKramer:初始化,而不是赋值。
  • 糟糕,我的错误,读得太快了。
  • 这两种初始化方式有什么区别。到目前为止,我认为两者都是相同的,即使用适当的构造函数(如果是相同的对象,则使用复制构造函数)

标签: c++ xcode clang


【解决方案1】:

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

它是CContainer&amp; operator=(CContainer&amp; p)。你在那里缺少const,它应该是CContainer&amp; operator=(CContainer const&amp; p)

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

【讨论】:

  • 谢谢@MSalters 我得到了 const 部分,但单独添加 const 似乎并没有解决问题,请您分享代码以确保我没有遗漏任何东西。我为派生构造函数 CContainerDerived(CContainer const& p) 添加了一个特化,现在它似乎解决了,rextester.com/XWE9303
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
  • 1970-01-01
  • 2014-02-08
相关资源
最近更新 更多