Avoiding implicit conversion in constructor. The 'explicit' keyword doesn't help here

前端 未结 7 1991
闹比i
闹比i 2020-12-29 18:07

I am able to avoid the implicit conversion of a constructor using the explicit keyword. So now, conversions like A a1 = 10; can be avoided.

相关标签:
7条回答
  • 2020-12-29 18:15

    To avoid int->double conversions everywhere, not only in your case. With g++ you can use -Wconversion -Werror. Note that it'll be allowed in your particular case, because the compiler understands that 10.0 is literal, but it will fail compilation for:

    class A
    {
    public:
        explicit A(int a)
        {
            num = a;
        }
    
        int num;
    };
    
    int main()
    {
        double x = 10;
        A a1 = A(x);
        static_cast<void>(a1);
        return 0;
    }
    

    Compiler explorer

    0 讨论(0)
  • 2020-12-29 18:16

    You can circumvent this problem by using braced initialization. For example:

    struct A {
      A(int _a) : a(_a) {}
      int a;
    };
    
    A a{5}; // ok
    A b{1.123}; // compile error
    

    Proof

    0 讨论(0)
  • 2020-12-29 18:18

    Explicitly delete the constructor for double (possibly add float):

    A(double) = delete;
    
    0 讨论(0)
  • 2020-12-29 18:20

    You should use the -Wconversion flag of gcc, that will generate a warning when implicitly casting a float to an int. Add -Werror to transform this warning (all in fact) into an error.

    0 讨论(0)
  • 2020-12-29 18:24

    You can delete A::A(<anything not an int>);:

    struct A
    {
        explicit A(int a)
        : num(a)
        {}
    
        template<class T>
        A(T) = delete;
    
        int num;
    };
    
    int main()
    {
        //A a1=A(10.0); // error: use of deleted function 'A::A(T) [with T = double]'
        A a2 = A(10); // OK
        (void) a2;
    }
    

    Demo: https://coliru.stacked-crooked.com/a/425afc19003697c9

    0 讨论(0)
  • 2020-12-29 18:24

    I just want to add that the A(double) = delete is a C++11 addition.

    If for whatever reason you cannot use this relatively new construct, you can simply declare it as private as this:

    class A{
      public:
        A(int);
      private:
        A(double);
    }
    
    0 讨论(0)
提交回复
热议问题