Reputation: 57248
I'm changing an old routine that used to take an integer parameter so that it now takes a const reference to an object. I was hoping that the compiler would tell me where the function is called from (because the parameter type is wrong), but the object has a constructor that takes an integer, so rather than failing, the compiler creates a temporary object, passing it the integer, and passes a reference to that to the routine. Sample code:
class thing {
public:
thing( int x ) {
printf( "Creating a thing(%d)\n", x );
}
};
class X {
public:
X( const thing &t ) {
printf( "Creating an X from a thing\n" );
}
};
int main( int, char ** ) {
thing a_thing( 5 );
X an_x( 6 );
return 1;
}
I want the X an_x( 6 )
line to not compile, because there is no X
constructor that takes an int
. But it does compile, and the output looks like:
Creating a thing(5)
Creating a thing(6)
Creating an X from a thing
How can I keep the thing( int )
constructor, but disallow the temporary object?
Upvotes: 7
Views: 548
Reputation: 57248
The explicit
keyword works perfectly in my example, but I realized later that my real world code was failing on an overloaded method, not the constructor. (My fault for asking a question that was similar to, but not the same as, my actual problem.) As Mark Ransom pointed out in the comments on the accepted answer, explicit
only works on constructors. I came up with a workaround that solved my problem, so I figured I'd post it here. New sample code:
class thing {
public:
thing( int x ) {
printf( "Creating a thing(%d)\n", x );
}
};
class X {
public:
void do_something( const thing &t ) {
printf( "Creating an X from a thing\n" );
}
};
int main( int, char ** ) {
thing a_thing( 5 );
X an_x;
an_x.do_something( 6 );
return 1;
}
This code shows the same output as the original code, but I can't use explicit
to fix it. Instead, I added a private method that takes an int
:
private:
void do_something( int x );
Now, the compiler doesn't create the temporary object, it gives an error because I am trying to call a private method from outside the class.
Upvotes: 1
Reputation: 57192
Use the explicit
keyword in the thing constructor.
class thing {
public:
explicit thing( int x ) {
printf( "Creating a thing(%d)\n", x );
}
};
This will prevent the compiler from implicitly calling the thing constructor when it finds an integer.
Upvotes: 11