问题
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 = {});
回答1:
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.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/35653230/is-it-possible-to-know-if-the-parameter-was-defaulted