我发现clang 3.8.0和gcc 6.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;
}
第一个异常是g ++(使用相同的命令行参数)抱怨PageProvider构造函数:
vitest.cpp:16:2: error: no matching function for call to ‘Processor::Processor()’
这可以通过取消注释处理器的显式初始化来解决,如上所示。根据下面的aschepler's answer,这是一个已知的gcc bug。
放弃了,事情变得更有趣:
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则不然。我得到了编译with gcc 5.1的相同结果。
我可以通过执行以下任何操作来说服gcc编译代码:
PageProvider
的构造函数的参数数量减少为1
(不论类型)。PageProvider
继承Processor
非虚拟。QuotePageProvider
构造函数的init-list中,将PageProvider
的初始化更改为使用括号而不是curlies。对上面Processor
的初始化进行的类似更改无效。这可能是标准中的一些奇怪的角落,两个编译器的解释方式不同,或者其中一个被破坏了?