简体   繁体   中英

How to check which constructor is used in C++

I modified the question here. Now it looks muck like a answer, :). Thank you all for sort this out.

I have some overloaded constructor in my class, Like this

#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){};
};

And a function declaration that actually accept A as a parameter

void func(const class A& a)
{
}

But the caller is invoking it by passing a enum .

int main()    
{
#ifdef EXPLICIT_ENUM_CONVERSION
  E e=E::A;
  func((unsigned int)e);  
#else
  E e=A;
  func(e);  
#endif
}

Question: By commenting out the A(unsigned) and compile again to get an error, I can tell that the constructor that is used. But is there a better way to tell how the types are converted from the gcc command line or objdump the result?

Answer: If compiling with -O0 and then use objdump -CSr, the class constructor used is shown from the objdump.

Question: is there any way to prevent the enum to unsigned automatic conversion with gcc?

Answer: See the answer I picked. The scoped enum is introduced in C++11 and can satisfy the purpose. You can check the code within EXPLICIT_ENUM_CONVERSION.

Here are 3 suggestions depending on your goal:

If you want to understand conversion rules better:

  1. read the relevant parts in the book Accelerated C++ (preference, steps in conversion)
  2. read the relevant parts in the book More Effective C++ (no more than 1 implicit conversion)
  3. read the C++ standard, eg the C++14 draft

If you want to find some bug :

  • use printf-debugging or logging in your ctors
  • or use a debugger
  • or break down your code into smaller steps, eg

     E e; auto i = static_cast<u32>(e); func(i); 

    static_cast<u32>(e) uses explicitly typed initializer idiom (see Effective Modern C++ Item 6)

If you want to avoid bugs , you should avoid too complex implicit conversions and be wary of user-defined conversion functions ( More Effective C++ Item 5). For instance:

  • explicit conversion ctor: explicit A(u32 i){};
  • scoped enum: enum class E{...}
  • scoped enum as ctor parameter: A(E enumElement){};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM