The compiler is allowed to make one implicit conversion to resolve the parameters to a function. What this means is that the compiler can use constructors callable with a single parameter to convert from one type to another in order to get the right type for a parameter.
Here's an example class with a constructor that can be used for implicit conversions:
class Foo
{
public:
// single parameter constructor, can be used as an implicit conversion
Foo (int foo) : m_foo (foo)
{
}
int GetFoo () { return m_foo; }
private:
int m_foo;
};
Here's a simple function that takes a Foo
object:
void DoBar (Foo foo)
{
int i = foo.GetFoo ();
}
and here's where the DoBar
function is called:
int main ()
{
DoBar (42);
}
The argument is not a Foo
object, but an int
. However, there exists a constructor for Foo
that takes an int
so this constructor can be used to convert the parameter to the correct type.
The compiler is allowed to do this once for each parameter.
Prefixing the explicit
keyword to the constructor prevents the compiler from using that constructor for implicit conversions. Adding it to the above class will create a compiler error at the function call DoBar (42)
. It is now necessary to call for conversion explicitly with DoBar (Foo (42))
The reason you might want to do this is to avoid accidental construction that can hide bugs.
Contrived example:
- You have a
MyString
class with a constructor that constructs a string of the given size. You have a function print(const MyString&)
(as well as an overload print (char *string)
), and you call print(3)
(when you actually intended to call print("3")
). You expect it to print "3", but it prints an empty string of length 3 instead.
Best Answer
The rules (which did not change in C++11):
std
namespace is reserved. (You are allowed to add template specializations, though.)From the 2003 C++ Standard:
Because C++ is based on the C standard (1.1/2, C++03) and C99 is a normative reference (1.2/1, C++03) these also apply, from the 1999 C Standard:
Other restrictions might apply. For example, the POSIX standard reserves a lot of identifiers that are likely to show up in normal code:
E
followed a digit or uppercase letter:is
orto
followed by a lowercase letterLC_
followed by an uppercase letterf
orl
are reservedSIG
followed by an uppercase letter are reservedSIG_
followed by an uppercase letter are reservedstr
,mem
, orwcs
followed by a lowercase letter are reservedPRI
orSCN
followed by any lowercase letter orX
are reserved_t
are reservedWhile using these names for your own purposes right now might not cause a problem, they do raise the possibility of conflict with future versions of that standard.
Personally I just don't start identifiers with underscores. New addition to my rule: Don't use double underscores anywhere, which is easy as I rarely use underscore.
After doing research on this article I no longer end my identifiers with
_t
as this is reserved by the POSIX standard.The rule about any identifier ending with
_t
surprised me a lot. I think that is a POSIX standard (not sure yet) looking for clarification and official chapter and verse. This is from the GNU libtool manual, listing reserved names.CesarB provided the following link to the POSIX 2004 reserved symbols and notes 'that many other reserved prefixes and suffixes ... can be found there'. The POSIX 2008 reserved symbols are defined here. The restrictions are somewhat more nuanced than those above.