Is it possible to know if the parameter was defaulted - c++

Caution: This problem is limited to MSVS
I have this function signature:
void do_somthing(std::vector<foo>& bar={});
Is it possible to differ between those two calls for the function:
First:
do_something()
Second:
std::vector<foo> v;
do_something(v);
In other words, I want something like:
void do_somthing(std::vector<foo>& bar={}){
if(/* bar was defaulted*/){
}
else{
}
}
EDIT:
The actual code:
template<class Tinput_iterator>
Tmodel perform_fitting(Tinput_iterator begin_data, Tinput_iterator end_data, std::vector<Tpoint>& inliers = {});

No, not directly. The default parameter is substituted by the compiler at the call site without any further information.
However, there is a simple solution to achieve what you want to do: Use overloading instead of default parameters.
namespace detail
{
void
do_something_impl(const std::vector<foo>& foos)
{
// Do things that always need to be done…
}
}
void
do_something()
{
// Do things specific to the no-argument case…
detail::do_something_impl({});
}
void
do_something(const std::vector<foo>& foos)
{
// Do things specific to the one-argument case…
detail::do_something_impl(foos);
}
If your logic requires you to branch more often – not just at the beginning or the end of the function – you could pass an additional boolean parameter to detail::do_something_impl that encodes which overload it was called from.
In general, I recommend to use defaulted parameters sparingly and prefer function overloading as it gives you better control and often also better (less surprising) interfaces.

I have this function signature:
void do_somthing(std::vector<foo>& bar=std::vector<foo>{});
This cannot compile, except with dangerous non-standard compiler settings you should stay away from.
In particular, Visual C++ allows this if /Za is not specified, but with /W4 still produces a warning like this:
stackoverflow.cpp(6): warning C4239: nonstandard extension used: 'default argument': conversion from 'std::vector<foo,std::allocator<_Ty>>' to 'std::vector<foo,
std::allocator<_Ty>> &'
with
[
_Ty=foo
]
stackoverflow.cpp(6): note: A non-const reference may only be bound to an lvalue
void do_somthing(std::vector<foo>& bar=std::vector<foo>{}){
if(/* bar was defaulted*/){
}
else{
}
}
Even if we assume that you actually included the missing const to make the code compile, the answer would be: no, it is not possible to know if bar was defaulted.
Whatever you plan to do here, you have to find a completely different solution.

Is it possible to differ between those two calls for the function?
No. You can check if the vector is empty, but otherwise there is no way to distinguish them.
You can do clever things, such as passing a utility class that converts, but that isn't bulletproof and is mostly pointless since you can more easily make two different function overloads.

Related

Default Arguments vs Overloading?

In WG21 N0131 Bill Gibbons states:
default arguments are often considered an anachronism because they can be replaced with overloaded functions
I understand that a single function like:
void f(T t = t0, U u = u0);
can be replaced by the three overloads:
void f() { f(t0); }
void f(T t) { f(t, u0); }
void f(T t, U u);
but what I don't understand is why the latter should be preferred over the former? (That is what he means by "anachronism", right?)
There's some related discussion in the Google styleguide here: Google C++ Styleguide > Default Arguments, but I don't see how it answers the question or supports Gibbons claim.
Anyone know what he's talking about? Why are default arguments considered an anarchronism?
From my own experience, the problem is that of violating the principle of least astonishment when interacting with other language features. Let's say you have a component that uses f a lot. I.e. you see this in plenty of places:
f();
From reading it, you assume you have a function that takes no arguments. So when you need to add interaction with some other component that has a registration function:
void register(void (*cb)());
you do the obvious thing...
register(f);
... and you immediately get a nice shiny error because the declared type of f is a function that takes two arguments. Wtf!? So you look at the declaration and understand... right...
The default arguments make your code behave a certain way via the compiler "fudging" the call site to make things work. It isn't really calling a function with no argument, but implicitly initializes two arguments to call the function with.
On the other hand, the overload set does behaves how one would expect. There is no "fudging" of the call site by the compiler, and when we try to register(f)... it works!
The one objective reason to prefer overloading
I've recently been presented an objective (well, what I think it is! :D) reason why one should prefer overloading to default arguments, at least when default values are non-builtin types: unnecessary #include directives in header files.
Default arguments should be an implementation detail, because you as the implementer take the decision of what argument to use on behalf of your client, if they don't provide it to you. Why should they be aware of your decision? So when you have a function declared like this
void doSomeWork(Foo, Bar = defaultBar);
you would really like defaultBar to be a "secret", not exposed to your includers.
At the moment you prefer default arguments, they you have to include in your header, all the headers that you need to be able to write defaultBar. How much can that cost to you?
Well, Bar could be a (reference or pointer to a) base class, and defaultBar is an object of a concrete class, so you're forced to include both the headers where one and the other classes are defined.
Or maybe Bar is std::function<bool(Foo const&, Foo const&)>, and its default value is actually an expression such as compose(std::less<>{}, convertToInt), you'd have the following in your header:
// ok with these
//#include "Foo.hpp" // in the code below you don't even need the definiton of
// Foo, so you could be happy with just it's forward header
#include "fwd/Foo.hpp" // this only declares Foo
#include <functional>
// but why these?
#include <boost/hana/functional/compose.hpp> // or alternative
#include "/path/to/convertToInt.hpp" // maybe this does bring with it Foo.hpp
using Bar = std::function<bool(Foo const&, Foo const&)>;
void doSomeWork(Foo const&, Bar = compose(std::less<>{}, convertToInt));
With overloads the header would be this
// ok with these
#include "fwd/Foo.hpp" // this only declares Foo
#include <functional>
using Bar = std::function<bool(Foo const&, Foo const&)>;
void doSomeWork(Foo const&, Bar);
void doSomeWork(Foo const&);
and only in the implementation, would you include the other headers too
#include "fwd/Foo.hpp"
#include "Foo.hpp"
#include <functional>
#include <boost/hana/functional/compose.hpp>
#include "/path/to/convertToInt.hpp"
void doSomeWork(Foo const& foo, Bar bar) {
// definition
}
void doSomeWork(Foo const& foo) {
doSomeWork(foo, compose(std::less<>{}, convertToInt));
}
Original answer
I would first of all refer to this article on FluentC++ which addresses this very question and gives a clear personal answer near to the top of the post:
By default, I think that we should prefer default parameters rather than overloads.
However, as the By default implies, the author gives merit to overloads in favour of default parameters is some peculiar situations.
My original answer follows, but I have to say: the article linked above did reduce substantially my repulsion for default arguments...
Given void f(T t = t0, U u = u0);, you have no way to call f with a custom u and letting t be the default t0 (unless you manually call f(t0, some_u), obviously).
With the overloads, it's easy: you just add f(U u) to the set of overloads.
So with overloads you can do what you can do with default arguments, plus more.
Besides, since with this question we are already in the land of opinions, why not mentioning the fact that you can re-declare functions by adding more defaults? (Example taken from cppreference.)
void f(int, int); // #1
void f(int, int = 7); // #2 OK: adds a default
void f(int = 1, int); // #3 OK, adds a default to #2
And the fact that the definition of a function cannot re-define a default argument if a previous declaration of the function defines it (for a pretty clear and understandable reason)?
void f(int, int = 7); // in a header file
void f(int, int) {} // in a cpp file correct
void f(int, int = 7) {} // in a cpp file wrong
Yes, maybe the default arguments are an "interface thing", so probably not seeing a sign of it in an implementation file is fine.
Anachronism means something that stands out for being in the present given that it is widely considered to be a thing of the past.
The rest of my answer is a matter of opinion... but the question itself supposes that there isn't a hard-and-fast "answer".
As for why default arguments are a thing of the past, there could be many examples.... the best one that comes to mind for myself however is that especially when writing a set of reusable functions, we want to reduce the potential for mis/incorrect use.
Consider the following:
void f(int i = 0, char c = 'A'){std::cout << i << c << std::endl;}
Now consider that someone attempts to use it as follows:
f('B');
They probably expected to see this output:
0B
What they get however is:
66A
Upon seeing the output they understand their mistake and correct it... but if you remove the default parameters and instead force the use of one of a couple of specific overloads that will accommodate a single parameter of either type... then you have made a more robust interface that provides what would be the expected output every time. The default arguments work... but they aren't necessarily the most "clear" in the case of development when someone forgets that if at least one argument is supplied in the function call, only the trailing arguments can be defaulted.
In the end, what matters is that the code works... but if you saw code with labels and goto statements, you'd be like, "oh really?". They work fine... but they can be misused. Switching languages to stress the subjective nature of the discussion in general... if JavaScript works well and provides so much freedom given the the nature of its variables having mutable type... why on earth would anyone want to use TypeScript? Its a matter of simplifying/enforcing proper reuse of the code. Otherwise who cares as long as it works...

Automatic Object Construction in Function Parameters by Passing Constructor Parameters

Can you explain why the following code compiles and runs? What is the concept at play here, and what are the limitations/requirements for such a methodology to work?
class string_wrapper
{
public:
string_wrapper(string i_string);
string m_value;
int m_length;
};
string_wrapper::string_wrapper(string i_string)
{
m_value = i_string;
m_length = i_string.length();
}
void bar(string_wrapper i_param)
{
cout << i_param.m_value << std::endl;
}
void foo()
{
string test_string = "test1";
bar(test_string);
}
int main()
{
test_function_b();
}
Output:
test1
I would expect this code to not compile. foo() is passing a string parameter to bar(), when bar only takes a string_wrapper parameter. However, the compiler is smart enough to know that it can use the string parameter as a parameter to a constructor for a string_parameter object, which presumably is then passed on as the actual parameter to bar().
Is this behavior within the C++ standard, or unique to my compiler (Visual Studio 2017, version 15.9, in this case)? Any insight or terminology I can use for further research would be appreciated.
Whats going on here is implicit construction. You are right about the compiler being 'smart' enough to know that you can create a string_wrapper out of a std::string and so does it automatically for you.
To stop this happening you can use the explcit keyword like this:
...
explicit string_wrapper(string i_string);
...
The explicit keyword tells the compiler that you do not want it to automatically construct string_wrapper objects for you out of std::string's. This can stop hard to track down bugs because it prevents accidentally constructing objects (especially on function returns and when passing arguments).
Implicit construction can happen when an object has only one non-defaulted parameter (implicit conversion is something you should research as well). It can be a powerful tool and can allow things like proxy classes and transparent APIs (i.e std::vector's reference class). Generally you should declare single parameter (or single undefaulted value) constructors (and conversion operators) explicit unless you are making a design decision not too.

Using decltype to declare the entire function type itself (not pointer!)

So I have a function with a specific signature in a header file, and I want to declare another function with the exact same signature inside a class without typing the parameters again, and of course, hopefully without a macro... The member function should also have an extra hidden parameter obviously, the this pointer (since it's not a static member function).
Now, I'm actually surprised that the following hack/trick works in both GCC and ICC, but I'm not sure if it's "legal" C++. I'm not particularly concerned with legality if it's a supported extension, but unfortunately I do not want it to break on a compiler version update because some people decided to arbitrarily block this useful feature since the standard says "no" (that kind of stuff really annoys me to be honest).
Here's what I mean:
// test.hpp
int func(int x) { return x; }
struct foo
{
decltype(func) fn; // <-- legal?
};
int test()
{
return foo().fn(6);
}
// then in test.cpp
int foo::fn(int x) { return x + 42; }
This works (with GCC and ICC), but I don't know if it's "legal" in the standard. I'm asking just to be assured that it is legal and it won't suddenly stop working in the future.
(if it's not legal and you want to report it as a bug, please mark it as a suggestion to make it a legal compiler extension instead of killing it...)
Basically, it's the same as declaring int fn(int x); in the struct, and that's how it works currently.
If you ask me for a use case: it's to declare a wrapper member function for the other free function which does something with the this pointer before passing it to the free function. Its parameters must match exactly, obviously. Again, I don't want to type the parameters again.
That looks legal; but at definition you have to retype. Consider using perfect forwarding instead.

Repeatedly Running A Function With Different Parameters Each Time

Currently, I have a struct which I've used to create a lot of parameters, then I have to run various functions on all of them.
Function1(Mom.SayHi);
Function1(Mom.BeNice);
Function1(Mom.MindManners);
Function3(Mom.SayHi);
Function3(Mom.BeNice);
Function3(Mom.MindManners);
and so on, and the issue is that I have a very long list of parameters that will probably expand. Is there a way to run a specified function on everything in the struct, like
xAllTheY(FunctionWut,AllParams){
FunctionWut(AllParams);
}
It seems that I can't use a function as a parameter. It may be because I'm using void functions. Am I missing an asterisk(*) or something?
I'm using MS Visual C++ 2010 Express, and I don't care about portability.
C++ does not have any feature to run a function on every field of the structure. You need to write a call for each field explicitly.
The reason for that is that C++ is sort of "low level language" if comparing it with recent languages. It tends to translate into instructions what is written in the source code.
I believe there are several ways to solve the task.
If you know that all functions have the same signature, you can use function pointer (or member function pointer) and array of potential arguments. Then you iterate over array of potential arguments and pass them to the function pointer. For instance:
void exec(void (*fun)(const std::string&), const std::vector<std::string>& args)
{
for (auto& v: args) { fun(v); }
}
You can achieve the same result (indeed, even better result due to function pointer optimization) by using template function (or functor), which accepts function and arguments list. This way you can adopt arbitrary functions to the same piece of code; moreover, you can adopt functions that accept more than one argument by using std::bind. For instance:
template <typename Fun, typename ArgsContainer>
void exec(Fun fun, const ArgsContainer& args)
{
for (auto& v: args) { fun(v); }
}
Actually, this is already done by for_each algorithm:
for_each(args.begin(), args.end(), &func);
Last but not least, you can use macros. Sometimes using macro+include to iterate over something is acceptable technique. For instance:
void exec(void (*fun)(const std::string&))
{
#define RUN(arg) fun((arg))
#include "run_cases.h"
#undef RUN
}
where run_cases.h looks like:
RUN("test1");
RUN(2.0f);
RUN(anything_that_is_acceptable_as_any_function_overload);
And no, you cannot pass just the name of the struct assuming compiler will substitute it with it's members. You have to explicitly type them in; actually, you don't want every struct member to be used, implicit ones are a good candidate for exclusion.

Default parameters with C++ constructors [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Is it good practice to have a class constructor that uses default parameters, or should I use separate overloaded constructors? For example:
// Use this...
class foo
{
private:
std::string name_;
unsigned int age_;
public:
foo(const std::string& name = "", const unsigned int age = 0) :
name_(name),
age_(age)
{
...
}
};
// Or this?
class foo
{
private:
std::string name_;
unsigned int age_;
public:
foo() :
name_(""),
age_(0)
{
}
foo(const std::string& name, const unsigned int age) :
name_(name),
age_(age)
{
...
}
};
Either version seems to work, e.g.:
foo f1;
foo f2("Name", 30);
Which style do you prefer or recommend and why?
Definitely a matter of style. I prefer constructors with default parameters, so long as the parameters make sense. Classes in the standard use them as well, which speaks in their favor.
One thing to watch out for is if you have defaults for all but one parameter, your class can be implicitly converted from that parameter type. Check out this thread for more info.
I'd go with the default arguments, especially since C++ doesn't let you chain constructors (so you end up having to duplicate the initialiser list, and possibly more, for each overload).
That said, there are some gotchas with default arguments, including the fact that constants may be inlined (and thereby become part of your class' binary interface). Another to watch out for is that adding default arguments can turn an explicit multi-argument constructor into an implicit one-argument constructor:
class Vehicle {
public:
Vehicle(int wheels, std::string name = "Mini");
};
Vehicle x = 5; // this compiles just fine... did you really want it to?
This discussion apply both to constructors, but also methods and functions.
Using default parameters?
The good thing is that you won't need to overload constructors/methods/functions for each case:
// Header
void doSomething(int i = 25) ;
// Source
void doSomething(int i)
{
// Do something with i
}
The bad thing is that you must declare your default in the header, so you have an hidden dependancy: Like when you change the code of an inlined function, if you change the default value in your header, you'll need to recompile all sources using this header to be sure they will use the new default.
If you don't, the sources will still use the old default value.
using overloaded constructors/methods/functions?
The good thing is that if your functions are not inlined, you then control the default value in the source by choosing how one function will behave. For example:
// Header
void doSomething() ;
void doSomething(int i) ;
// Source
void doSomething()
{
doSomething(25) ;
}
void doSomething(int i)
{
// Do something with i
}
The problem is that you have to maintain multiple constructors/methods/functions, and their forwardings.
In my experience, default parameters seem cool at the time and make my laziness factor happy, but then down the road I'm using the class and I am surprised when the default kicks in. So I don't really think it's a good idea; better to have a className::className() and then a className::init(arglist). Just for that maintainability edge.
Sam's answer gives the reason that default arguments are preferable for constructors rather than overloading. I just want to add that C++-0x will allow delegation from one constructor to another, thereby removing the need for defaults.
Either approach works. But if you have a long list of optional parameters make a default constructor and then have your set function return a reference to this. Then chain the settors.
class Thingy2
{
public:
enum Color{red,gree,blue};
Thingy2();
Thingy2 & color(Color);
Color color()const;
Thingy2 & length(double);
double length()const;
Thingy2 & width(double);
double width()const;
Thingy2 & height(double);
double height()const;
Thingy2 & rotationX(double);
double rotationX()const;
Thingy2 & rotatationY(double);
double rotatationY()const;
Thingy2 & rotationZ(double);
double rotationZ()const;
}
main()
{
// gets default rotations
Thingy2 * foo=new Thingy2().color(ret)
.length(1).width(4).height(9)
// gets default color and sizes
Thingy2 * bar=new Thingy2()
.rotationX(0.0).rotationY(PI),rotationZ(0.5*PI);
// everything specified.
Thingy2 * thing=new Thingy2().color(ret)
.length(1).width(4).height(9)
.rotationX(0.0).rotationY(PI),rotationZ(0.5*PI);
}
Now when constructing the objects you can pick an choose which properties to override and which ones you have set are explicitly named. Much more readable :)
Also, you no longer have to remember the order of the arguments to the constructor.
One more thing to consider is whether or not the class could be used in an array:
foo bar[400];
In this scenario, there is no advantage to using the default parameter.
This would certainly NOT work:
foo bar("david", 34)[400]; // NOPE
Mostly personal choice. However, overload can do anything default parameter can do, but not vice versa.
Example:
You can use overload to write A(int x, foo& a) and A(int x), but you cannot use default parameter to write A(int x, foo& = null).
The general rule is to use whatever makes sense and makes the code more readable.
If creating constructors with arguments is bad (as many would argue), then making them with default arguments is even worse. I've recently started to come around to the opinion that ctor arguments are bad, because your ctor logic should be as minimal as possible. How do you deal with error handling in the ctor, should somebody pass in an argument that doesn't make any sense? You can either throw an exception, which is bad news unless all of your callers are prepared to wrap any "new" calls inside of try blocks, or setting some "is-initialized" member variable, which is kind of a dirty hack.
Therefore, the only way to make sure that the arguments passed into the initialization stage of your object is to set up a separate initialize() method where you can check the return code.
The use of default arguments is bad for two reasons; first of all, if you want to add another argument to the ctor, then you are stuck putting it at the beginning and changing the entire API. Furthermore, most programmers are accustomed to figuring out an API by the way that it's used in practice -- this is especially true for non-public API's used inside of an organization where formal documentation may not exist. When other programmers see that the majority of the calls don't contain any arguments, they will do the same, remaining blissfully unaware of the default behavior your default arguments impose on them.
Also, it's worth noting that the google C++ style guide shuns both ctor arguments (unless absolutely necessary), and default arguments to functions or methods.
I would go with the default parameters, for this reason: Your example assumes that ctor parameters directly correspond to member variables. But what if that is not the case, and you have to process the parameters before the object is initialize. Having one common ctor would be the best way to go.
One thing bothering me with default parameters is that you can't specify the last parameters but use the default values for the first ones. For example, in your code, you can't create a Foo with no name but a given age (however, if I remember correctly, this will be possible in C++0x, with the unified constructing syntax). Sometimes, this makes sense, but it can also be really awkward.
In my opinion, there is no rule of thumb. Personnaly, I tend to use multiple overloaded constructors (or methods), except if only the last argument needs a default value.
Matter of style, but as Matt said, definitely consider marking constructors with default arguments which would allow implicit conversion as 'explicit' to avoid unintended automatic conversion. It's not a requirement (and may not be preferable if you're making a wrapper class which you want to implicitly convert to), but it can prevent errors.
I personally like defaults when appropriate, because I dislike repeated code. YMMV.