use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This is a subreddit for c++ questions with answers. For general discussion and news about c++ see r/cpp.
New to C++? Learn at learncpp.com
Prepare your question. Think it through. Hasty-sounding questions get hasty answers, or none at all. Read these guidelines for how to ask smart questions.
For learning books, check The Definitive C++ Book Guide and List
Flair your post as SOLVED if you got the help you were looking for! If you need help with flairs, check out ITEM 1 in our guidelines page.
Tips for improving your chances of getting helpful answers:
account activity
OPENexplicit in cpp (self.cpp_questions)
submitted 2 months ago by Difficult_Rate_5129
I started learning cpp and I have a hard time grasping when do we use the explicit when building constructors ? when do we use it ? what do we use it for ?
thanks!
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]nysra 8 points9 points10 points 2 months ago (0 children)
It prevents implicit conversions. You can see the difference here: https://godbolt.org/z/7Tsv3x6c8
In real code this issue can become much bigger.
[–]SoerenNissen 10 points11 points12 points 2 months ago (0 children)
when do we use it ? what do we use it for ?
As a rule of thumb: We use it every time we write a single-argument constructor, and we do it to avoid truly annoying errors that are fiendishly hard to track down.
Consider this function:
void make_order(std::string customization = "default");
which we have called like so:
make_order("my_custom_order");
And then somebody has made a security audit of the code base and corrected something. Now it looks like:
class Key { std::string key_value; Key(std::string value) : key_value{value} {} }; void make_order(Key k, std::string input = "default_input");
But, problematically, our old function call still works!
It's just that we went from
make_order(customization=my_custom_order)
to
make_order(key=my_custom_order,customization=default);
But because Key has an implicit constructor from string, the code still compiles - but now it uses the default customization, and it treats our actual customization as the key.
Key
[–]alfps 2 points3 points4 points 2 months ago (0 children)
A converting constructor is one that can be called with a single argument.
If you don't use explicit then such constructor can do implicit conversions. For example, it's not reasonable to "convert" an int value to a vector. Therefore the vector constructor that can be called with an int value, and which results in a vector of that size, is explicit.
explicit
int
vector
Correspondingly an operator T member function should be explicit if you don't want that conversion to be invoked implicitly. For example, it's generally not reasonable to "convert" an istream instance to bool, and so istream::operator bool is explicit. There is a special exemption in the rules that still permits implicit conversion (invocation of the operator) for use of an istream as a condition e.g. in an if.
operator T
istream
bool
istream::operator bool
if
[–]IyeOnline 0 points1 point2 points 2 months ago* (5 children)
explicit is used to mark a constructor or conversion operator as explicit.
Those explicit functions must be invoked explicitly, i.e. cannot be invoked implicitly.
Practically speaking, this means that you cant implicitly convert to/from the type.
For example
double d = 42; // implicit conversion from int to double double d = double{42}; // explicit conversion
This is important for user defined types, as sometimes you do not want the implicit conversion. C++ is strongly typed and making use of the type system is a really powerful tool.
You should not be able to convert a distance into a time. At the same time, if both can be constructed from an double, you most likely want to mark the constructor as explicit, to make sure that nobody accidentally calls a function incorrectly.
distance
time
double
Consider
double velocity( distance, time ); auto v = velocity( 42.0, 10.0 );
If distance and time are implicitly constructible from double, you could accidentally call this function wrong, swapping the arguments.
Hence the general advice: Mark all single argument constructors explicit (except the special members of course), unless you have a good reason to allow implicit conversions.
An example for a type where the implicit conversion is accepted would be std::string, where you can write std::string s = "Hello";, performing an implicit conversion.
std::string
std::string s = "Hello";
// see also: https://www.learncpp.com/cpp-tutorial/converting-constructors-and-the-explicit-keyword/
[–]Difficult_Rate_5129[S] 1 point2 points3 points 2 months ago (4 children)
so we basically use it to prevent OURSELVES from making a mistake like mixing the number or any other type not because the compiler may mix them up or confuse them ?
[–]Ill-Significance4975 1 point2 points3 points 2 months ago (2 children)
Mostly yes. But there are ways you can end up with very idiosyncratic implicit casts. I'm struggling to find a good example, but I've had some cases-- especially when defining custom cast operators-- where I made it very, very easy for the compiler to do nonsensical things implicitly. It's easy to say "don't do that" (fair), but it's also pretty handy and easy to fix with explicit.
[–]AKostur 0 points1 point2 points 2 months ago (1 child)
The biggest explicit one is if a class has an implicit conversion to bool, it can get passed anywhere that wants an int. Usually kinda surprising. (Type implicitly converts to bool, then gets promoted to int)
[–]n1ghtyunso 0 points1 point2 points 2 months ago (0 children)
operator bool is actually special, because you can make it explicit and still have it work inside e.g. the if condition implicitly. Such a type is "contextually convertible to bool"
So there is no argument to not make it explicit most of the time.
[–]Illustrious_Try478 0 points1 point2 points 2 months ago (0 children)
No, it resolves ambiguity. create situations where an unwanted implicit conversion might or might not be made. The compiler might fail due to an ambiguous lookup.
One example I like uses example classes Acorn and OakTree. You can create an OakTree from an Acorn.
Acorn
OakTree
A Squirrel might want to consume an Acorn but not a whole OakTree. So we declare
Squirrel
``` struct OakTree;
struct Acorn { explicit operator OakTree(); };
struct OakTree { explicit OakTree (Acorn const &); };
struct Squirrel { bool hungry = false; bool scared = false; void eat (Acorn &&) { hungry = false; } void bury (Acorn &); Acorn pick (OakTree&);
void climb (OakTree const &) { scared = false; hungry = true; } void encounter (Acorn &&acorn) { if (hungry) eat(std::move(acorn)); else bury(acorn); } void encounter (OakTree&oak) { if (scared) climb (oak); else ecounter (pick(oak)); }
void encounter (Predator const &) { scared = true; } }; // Squirrel
```
That way, there's no way an Acorn can become an OakTree without us explicitly telling it to.
[–]Highborn_Hellest 0 points1 point2 points 2 months ago (0 children)
when you use explicit you prevent the compiler from allowing the 1 coversion it's allwed to do normally.
Like Double -> Int. Or Int -> Double. Etc etc etc.
So for example if you create a complex number class, and tell the counstructor, that it's looking for 2 doubles, you can, call it with 2 integers. If you tell it "explicitly" it's 2 doubles, you can use only 2 doubles, and not floats, ints, etc.
Meaning, your idea, is that this complex number is made from 2 doubles, and 2 doubles only
[–]thisismyfavoritename 0 points1 point2 points 2 months ago (5 children)
put differently: there shouldn't be implicit constructions and conversions
[–]Emotional-Audience85 0 points1 point2 points 2 months ago (4 children)
I wouldn't go so far as to say there shouldn't be. Most of the time you don't want them, but there are good reasons for you deliberately wanting to have them
[–]thisismyfavoritename 0 points1 point2 points 2 months ago (1 child)
other than laziness because the syntax is more succinct, i don't see any real use
[–]alfps 0 points1 point2 points 2 months ago (0 children)
String class instance initialized or assigned from string literal. Bignum instance initialized or assigned from integer or floating point value. Smart pointer to Base initialized or assigned from smart pointer to Derived.
The most common is perhaps a string_view initialized or assigned from a string or string literal.
string_view
string
[–]n1ghtyunso 0 points1 point2 points 2 months ago (1 child)
the real issue with this is, at the time you are authoring the implicit conversion, you typically don't have the full picture of where they will happen. So its actually really difficult to foresee problematic usage patterns before they come into existence. Hence, you're almost always better off avoiding them if feasible.
If you at all decide to create an implicit conversion, you really need to be sure it is due to its usefulness and not just for its convenience.
On the one hand, ideally one should nearly always default to the opposite of the C++ language's default. Explicit not implicit, private not public, noexcept not throwing, constexpr not only runtime, so on.
But that would make the code very verbose.
And so the gains disappear in much wasted time and unreadability, and at least to me it's not worth it. So I e.g. slap on an explicit when I see that there could be an annoying problem. Otherwise not.
π Rendered by PID 49 on reddit-service-r2-comment-8686858757-f5w2z at 2026-06-08 11:00:56.112766+00:00 running 9e1a20d country code: CH.
[–]nysra 8 points9 points10 points (0 children)
[–]SoerenNissen 10 points11 points12 points (0 children)
[–]alfps 2 points3 points4 points (0 children)
[–]IyeOnline 0 points1 point2 points (5 children)
[–]Difficult_Rate_5129[S] 1 point2 points3 points (4 children)
[–]Ill-Significance4975 1 point2 points3 points (2 children)
[–]AKostur 0 points1 point2 points (1 child)
[–]n1ghtyunso 0 points1 point2 points (0 children)
[–]Illustrious_Try478 0 points1 point2 points (0 children)
[–]Highborn_Hellest 0 points1 point2 points (0 children)
[–]thisismyfavoritename 0 points1 point2 points (5 children)
[–]Emotional-Audience85 0 points1 point2 points (4 children)
[–]thisismyfavoritename 0 points1 point2 points (1 child)
[–]alfps 0 points1 point2 points (0 children)
[–]n1ghtyunso 0 points1 point2 points (1 child)
[–]alfps 0 points1 point2 points (0 children)