从构造函数二进制兼容中删除 'explicit' 吗?
Is removing 'explicit' from a constructor binary compatible?
我们正在使用的外部库包含以下显式构造函数:
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
在这种情况下无论如何都没有意义。谁能确认一下?
如果你明白我的意思,你最好的选择是在包含期间关闭该警告。 不要破解供应商代码。
对多参数构造函数使用 explicit
在 C++11 之后非常有意义,因为它可以用于停止隐式大括号初始化。此外,标准 没有 说删除 explicit
必须保留 class 的 布局 ,因此您必须假设删除 explicit
可能会 破坏二进制兼容性。此外,删除它 可能 改变人为的 SFINAE 模式的行为,因为该构造函数在某些情况下可能会重新可用。参见 http://en.cppreference.com/w/cpp/language/sfinae。
explicit
在 C++11 及更高版本的 brace-initializers 上下文中对多个参数有意义:
void foo(Chart const &);
// ...
// Will only compile without `explicit`
foo({Chart::Type::pie, myObj});
是否 binary-compatible 删除 explicit
最终取决于您的编译器,因此您必须在其文档中找到它。
但是,由于 explicit
是一种 high-level 语言功能,它仅用于引导重载解析,我不认为它会破坏兼容性 只要它不改变某些 pre-existing 调用的最佳匹配是什么,包括您从库本身编译的任何代码(模板 and/or 内联函数).
也就是说,这是纯粹的 ad-hoc 修补:根据标准,这样做会让您直接进入 UB 领域。引用n.m.的评论:
Fiddling with headers like that breaks ODR. Vendor's binaries are compiled with a certain definition of a class, your binaries are compiled with a different definition of the same class. That's illegal. It doesn't matter how small the change is. The definitions must be token-by-token identical, period.
我建议简单地消除这些 header 中的警告,方法是将它们包装在包含的 #pragma
中(或在自定义代理 header 中,并包含).
我们正在使用的外部库包含以下显式构造函数:
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
在这种情况下无论如何都没有意义。谁能确认一下?
如果你明白我的意思,你最好的选择是在包含期间关闭该警告。 不要破解供应商代码。
对多参数构造函数使用 explicit
在 C++11 之后非常有意义,因为它可以用于停止隐式大括号初始化。此外,标准 没有 说删除 explicit
必须保留 class 的 布局 ,因此您必须假设删除 explicit
可能会 破坏二进制兼容性。此外,删除它 可能 改变人为的 SFINAE 模式的行为,因为该构造函数在某些情况下可能会重新可用。参见 http://en.cppreference.com/w/cpp/language/sfinae。
explicit
在 C++11 及更高版本的 brace-initializers 上下文中对多个参数有意义:
void foo(Chart const &);
// ...
// Will only compile without `explicit`
foo({Chart::Type::pie, myObj});
是否 binary-compatible 删除 explicit
最终取决于您的编译器,因此您必须在其文档中找到它。
但是,由于 explicit
是一种 high-level 语言功能,它仅用于引导重载解析,我不认为它会破坏兼容性 只要它不改变某些 pre-existing 调用的最佳匹配是什么,包括您从库本身编译的任何代码(模板 and/or 内联函数).
也就是说,这是纯粹的 ad-hoc 修补:根据标准,这样做会让您直接进入 UB 领域。引用n.m.的评论:
Fiddling with headers like that breaks ODR. Vendor's binaries are compiled with a certain definition of a class, your binaries are compiled with a different definition of the same class. That's illegal. It doesn't matter how small the change is. The definitions must be token-by-token identical, period.
我建议简单地消除这些 header 中的警告,方法是将它们包装在包含的 #pragma
中(或在自定义代理 header 中,并包含).