在clang ++中通过值怪异传递抽象对象

时间:2015-03-27 07:53:59

标签: c++

为什么clang ++ 3.6会编译下面的代码(g ++没有' t)?

class Abc
{
public:
    virtual void foo() const = 0;
    virtual ~Abc() {}
};

// is correctly rejected
// void bar(Abc o)
// {
// }

class B
{
    void bar(Abc o) // should also be rejected
    {
    }

};

int main()
{
}

我正在使用clang 3.6和gcc 4.9.2。

为什么自由功能(正确)被拒绝而成员功能没有?

任何提示? clang中的Bug?

如果我将上述内容修改为:

class Abc
{
public:
    virtual void foo() const = 0;
    virtual ~Abc() {}
};
class Impl : public Abc {
public:
    void foo() const {}
};
class B
{
public:
    void bar(Abc o)
    {
        o.foo();
    }
};
int main()
{
    B b;
    Impl i;
    b.bar(i);
}

我得到了

main.cc:16:未定义引用`abc :: foo()const'

链接器错误。

所以问题是:为什么允许clang ++编译这个错误的代码? 我会说这是一个重虫!

1 个答案:

答案 0 :(得分:1)

作为N4296 10.4 [class.abstract] 表示:

  

抽象类不能用作参数类型,作为函数   返回类型,或显式转换的类型。指针和   可以声明对抽象类的引用。

[ Example:
shape x;//  error: object of abstract class
shape* p;// OK
shape f();// error
void g(shape);// error
shape& h(shape&);//OK
— end example ]

所以gcc遵循标准。

为什么不能将参数声明为抽象类型?假设当一个pass子类对象变为bar,对象切片发生时,哦,一个具有纯虚函数的对象......这是一个矛盾。这可能是原因。

编辑:

为什么clang传递它,这是clang编译器问题。