正在删除'明确'从构造函数二进制兼容?

时间:2016-09-14 08:04:52

标签: c++ c++03 explicit-constructor

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

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

编译器抱怨以下警告:

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

是否只是二进制兼容才能删除chart.h中的explicit关键字,而无需重新编译库以避免警告?我的感觉是安全,因为explicit无论如何都没有意义。任何人都可以确认吗?

2 个答案:

答案 0 :(得分:9)

一个国家英里的最佳选择是,如果你了解我的意思,请在该包含期间关闭该警告。 不要破解供应商代码。

explicit用于多参数构造函数在C ++ 11之后非常有意义,因为它可用于停止隐式括号初始化。此外,标准没有表示删除explicit必须保留该类的布局,因此您必须假设删除explicit < em>可以打破二进制兼容性。另外,删除可以改变人为SFINAE模式的行为,因为构造函数在某些情况下可能会重新可用。请参阅http://en.cppreference.com/w/cpp/language/sfinae

答案 1 :(得分:2)

explicit在C ++ 11及以上版本的brace-initializers上下文中使用多个参数是有意义的:

void foo(Chart const &);

// ...

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

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

但是,由于explicit是一种高级语言功能,只会导致重载决策,我不希望它会破坏兼容性,只要它不会改变最佳匹配是什么一些预先存在的调用,包括从库本身编译的任何代码(模板和/或内联函数)

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

  

摆弄像这样的标题打破了ODR。供应商的二进制文件使用某个类的某个定义进行编译,您的二进制文件使用相同类的不同定义进行编译。那是违法的。变化有多小并不重要。定义必须是逐个令牌的相同的句点。

我建议简单地将这些标题中的警告静音,方法是将它们包含在#pragma所包含的位置(或自定义代理标头中,并包含该标题)。

相关问题