我在这里修改了问题。现在看起来很像一个答案,:)。谢谢大家解决这个问题。
我的类中有一些重载的构造函数,就像这样
#include <string>
#ifdef EXPLICIT_ENUM_CONVERSION
enum struct E
#else
enum E
#endif
{
A,
B
};
class A
{
public:
A(unsigned int i){};
A(std::string const& s){};
};
以及一个实际上接受 A 作为参数的函数声明
void func(const class A& a)
{
}
但是调用者通过传递枚举
来调用它。
int main()
{
#ifdef EXPLICIT_ENUM_CONVERSION
E e=E::A;
func((unsigned int)e);
#else
E e=A;
func(e);
#endif
}
问题:通过注释掉A(unsigned)
并再次编译得到错误,我可以知道所使用的构造函数。但是有没有更好的方法来告诉如何从 gcc
命令行或 objdump
结果转换类型?
解答:如果使用 -O0 编译,然后使用 objdump -CSr,则使用的类构造函数会从 objdump 中显示。
问题:有什么办法可以阻止 gcc 将enum
自动转换为unsigned
吗?
答案:请参阅我选择的答案。 C++11中引入了作用域枚举,可以满足此目的。您可以检查 EXPLICIT_ENUM_CONVERSION 中的代码。
最佳答案
根据您的目标,这里有 3 条建议:
如果您想更好地了解转换规则:
- 阅读书中的相关部分Accelerated C++ (偏好、转换步骤)
- 阅读书中的相关部分More Effective C++ (隐式转换不超过 1 次)
- 阅读C++ standard, e.g. the C++14 draft
如果您想找到一些错误:
- 使用 printf 调试或登录您的 ctors
- 或使用调试器
或者将您的代码分解为更小的步骤,例如
E e; auto i = static_cast<u32>(e); func(i);
static_cast<u32>(e)
使用显式类型化的初始化惯用法(请参阅 Effective Modern C++ 第 6 项)
如果您想避免错误,则应避免过于复杂的隐式转换,并警惕用户定义的转换函数(More Effective C++ 第 5 项)。例如:
- 显式转换因子:
explicit A(u32 i){};
- 作用域枚举:
enum class E{...}
- 作用域枚举作为 ctor 参数:
A(E enumElement){};
关于c++ - 如何检查C++中使用了哪个构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41503479/