This is referred to as a converting constructor (or sometimes implicit constructor or implicit conversion).
I'm not aware of a compile-time switch to warn when this occurs, but it's very easy to prevent; just use the explicit keyword.
class Texture { public: explicit Texture(const std::string& imageFile); }; As to whether or not converting constructors are a good idea: It depends.
Circumstances in which implicit conversion makes sense:
- The class is cheap enough to construct that you don't care if it's implicitly constructed.
- Some classes are conceptually similar to their arguments (such as
std::stringreflecting the same concept as theconst char *it can implicitly convert from), so implicit conversion makes sense. - Some classes become a lot more unpleasant to use if implicit conversion is disabled. (Think of having to explicitly invoke std::string every time you want to pass a string literal. Parts of Boost are similar.)
Circumstances in which implicit conversion makes less sense:
- Construction is expensive (such as your Texture example, which requires loading and parsing a graphic file).
- Classes are conceptually very dissimilar to their arguments. Consider, for example, an array-like container that takes its size as an argument:
class FlagList { FlagList(int initial_size); }; void SetFlags(const FlagList& flag_list); int main() { // Now this compiles, even though it's not at all obvious // what it's doing. SetFlags(42); } - Construction may have unwanted side effects. For example, an
AnsiStringclass should not implicitly construct from aUnicodeString, since the Unicode-to-ANSI conversion may lose information.
Further reading:
- The C++ FAQ on explicit constructors
- The Google C++ Style Guide says to nearly always use explicit constructors.
- This StackOverflow questionThis StackOverflow question goes into more pros and cons.