从构造函数二进制中删除"显式"是否兼容?



我们使用的外部库包含以下显式构造函数:

class Chart {
public:
    explicit Chart(Chart::Type type, Object *parent);
    // ...
};

编译器发出以下警告:

chart.h: warning #2305: declaration of 'explicit' constructor
without a single argument is redundant

是二进制兼容只是删除explicit关键字在chart.h没有重新编译库,以避免警告?我的感觉是它是安全的,因为explicit在这种情况下没有意义。有人能证实吗?

最好的办法是在包含期间关闭警告,如果您明白我的意思的话。不要破解厂商代码

在c++ 11以后的多参数构造函数中使用explicit是完全有意义的,因为它可以用来停止隐式大括号初始化。此外,标准并没有说删除explicit必须保留类的布局,所以您必须假设删除explicit 可能会破坏二进制兼容性。此外,删除可以改变人造SFINAE模式的行为,因为该构造函数在某些情况下可以重新可用。参见http://en.cppreference.com/w/cpp/language/sfinae。

explicit在c++ 11及以上版本的大括号初始化式上下文中对于多个形参是有意义的:

void foo(Chart const &);
// ...
// Will only compile without `explicit`
foo({Chart::Type::pie, myObj});

删除explicit是否与二进制兼容最终取决于您的编译器,因此您必须在其文档中找到。

然而,由于explicit是一个高级语言特性,只引导重载解析,我不希望它破坏兼容性,只要它不改变一些预先存在的调用的最佳匹配,包括从库本身编译的任何代码(模板和/或内联函数)

也就是说,这是纯粹的临时补丁:根据标准,这样做会让你直接进入UB领域。引自n.m.。的评论:

摆弄这样的头会破坏ODR。供应商的二进制文件是用一个类的特定定义编译的,你的二进制文件是用同一个类的不同定义编译的。这是非法的。不管变化有多小。定义必须每个令牌都相同,句号。

我建议在这些报头中简单地沉默警告,通过将它们包装在#pragma中(或在自定义代理报头中,并包括它)。

相关内容

最新更新