Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How explicit must you be when calling a constructor?

Tags:

c++

c++11

I have this class

struct foo
{
    explicit foo(const std::uint32_t& x, const std::uint32_t& y);
};

and a method

int main()
{
    std::int32_t x = -1;
    std::int32_t y = -1;
    foo f(x, y);
}

On my compiler (MSVC2012), this compiles and runs with the values x and y wrapped around to unsigned types. I was not expecting this, but was expecting a compile error due to mismatched types.

What am I missing?

like image 946
P45 Imminent Avatar asked Sep 24 '14 15:09

P45 Imminent


People also ask

How do you explicitly call a constructor?

The this keyword in Java is a reference to the object of the current class. Using it, you can refer a field, method or, constructor of a class. Therefore, if you need to invoke a constructor explicitly you can do so, using "this()".

What is an explicit constructor in Java?

Explicit means done by the programmer. Implicit means done by the JVM or the tool , not the Programmer. For Example: Java will provide us default constructor implicitly. Even if the programmer didn't write code for constructor, he can call default constructor.

What happens when we call a constructor explicitly?

When the constructor is called explicitly the compiler creates a nameless temporary object and it is immediately destroyed.

How are constructors called implicitly and explicitly?

The constructors can be called explicitly or implicitly. The method of calling the constructor implicitly is also called the shorthand method. Example e = Example(0, 50); // Explicit call. Example e2(0, 50); // Implicit call.


1 Answers

You're out of luck, the standard does allow implicit conversion of signed to unsigned via the creation of an anonymous temporary for an argument passed by constant reference.

(Note this is not true for a non-constant reference).

If you're using C++11, the best thing to do is to delete the constructor using

foo(const std::int32_t& x, const std::int32_t& y) = delete;

Pre C++11 you could make this constructor private and not define it. Rather like the old-fashioned not-copyable idioms.

MSVC2012 is a sort of half-way house C++03 / C++11 compiler. It implements some C++11 features but not others. Unfortunately deletion of constructors is one of the features it does not support so the privateisation approach is the best method available to you.

like image 106
Bathsheba Avatar answered Nov 15 '22 12:11

Bathsheba