Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么clang和gcc不同意这个虚拟继承代码?_C++_C++11_G++_Clang++ - Fatal编程技术网

C++ 为什么clang和gcc不同意这个虚拟继承代码?

C++ 为什么clang和gcc不同意这个虚拟继承代码?,c++,c++11,g++,clang++,C++,C++11,G++,Clang++,我看到了Clang3.8.0和GCC6.2.1在处理我认为有效的代码方面的一些差异。下面是一个示例,clang++--std=c++11 vitest.cpp编译时没有注释: #include <iostream> class Processor { public: Processor( int i, float f ) {} virtual ~Processor() noexcept {} virtual void getStatistics() =

我看到了Clang3.8.0和GCC6.2.1在处理我认为有效的代码方面的一些差异。下面是一个示例,
clang++--std=c++11 vitest.cpp
编译时没有注释:

#include <iostream>

class Processor {
public:
    Processor( int i, float f ) {}

    virtual ~Processor() noexcept {}

    virtual void getStatistics() = 0;
};

class PageProvider : virtual public Processor {
public:
    PageProvider( int i, float f )
//      : Processor{i,f}    // Without this, GCC wants to call default ctor
    {}

    virtual ~PageProvider() {}
};

class QuotePageProvider : public PageProvider {
public:
    QuotePageProvider( int i, float f )
        : Processor{i,f},
            PageProvider{i,f}
    {}

    virtual void getStatistics() { std::cout << "Hi there" << std::endl; };
};

int main( int argc, char* argv[] )
{
    PageProvider*   prov2{new QuotePageProvider{1,2.2}};
    prov2->getStatistics();
    delete prov2;
}
这可以通过取消注释处理器的显式初始化来解决,如上图所示。根据下面的说明,这是一个已知的gcc错误

抛开这些,事情变得更有趣了:

vitest.cpp: In constructor ‘QuotePageProvider::QuotePageProvider(int, float)’:
vitest.cpp:25:20: error: cannot allocate an object of abstract type ‘PageProvider’
    PageProvider{i,f}
                    ^
vitest.cpp:12:7: note:   because the following virtual functions are pure within ‘PageProvider’:
 class PageProvider : virtual public Processor {
       ^~~~~~~~~~~~
vitest.cpp:9:15: note:  virtual void Processor::getStatistics()
  virtual void getStatistics() = 0;
               ^~~~~~~~~~~~~
似乎gcc坚持要在
PageProvider
中提供getStatistics()的实现,以便编译
QuotePageProvider
,而clang没有。我得到了同样的结果

我可以通过执行以下任一操作说服gcc编译代码:

  • PageProvider
    的构造函数的参数数减少为1 (不分类型)
  • 使
    PageProvider
    处理器的继承成为非虚拟的
  • QuotePageProvider
    的构造函数的init列表中,将
    PageProvider
    的初始化更改为使用括号而不是卷曲。与上面的
    处理器
    初始化类似的更改不会产生任何影响
这可能是标准中的一些奇怪的角落,两个编译器有不同的解释,或者其中一个被破坏了吗?

这是gcc错误

抽象类不需要构造它的虚拟基类。

这是gcc错误


抽象类不需要构造其虚拟基类。

感谢您的参考,但这似乎只是问题的第一部分。如果PageProvider显式初始化处理器,这似乎可以解决您引用的错误,但仍然存在编译器希望实现getStatistics()的问题。或者你是说他们有某种联系?谢谢你的参考,但这似乎只是问题的第一部分。如果PageProvider显式初始化处理器,这似乎可以解决您引用的错误,但仍然存在编译器希望实现getStatistics()的问题。或者你是说他们有某种关联?下半部分是另一个GCC错误。(好吧,这是标准IIRC中的一个bug,它得到了不折不扣的实现,然后标准得到了修复,然后GCC得到了修复,但还没有完全修复。)@T.C.宾果,看起来就是这样。如果你想将你的评论升级为一个答案,我会接受。下半部分是另一个GCC错误。(好吧,这是标准IIRC中的一个bug,它得到了不折不扣的实现,然后标准得到了修复,然后GCC得到了修复,但还没有完全修复。)@T.C.宾果,看起来就是这样。如果你想把你的评论升级为答案,我会接受的。
vitest.cpp: In constructor ‘QuotePageProvider::QuotePageProvider(int, float)’:
vitest.cpp:25:20: error: cannot allocate an object of abstract type ‘PageProvider’
    PageProvider{i,f}
                    ^
vitest.cpp:12:7: note:   because the following virtual functions are pure within ‘PageProvider’:
 class PageProvider : virtual public Processor {
       ^~~~~~~~~~~~
vitest.cpp:9:15: note:  virtual void Processor::getStatistics()
  virtual void getStatistics() = 0;
               ^~~~~~~~~~~~~