
Wait, this is an exact copy of an example you have in "controlling overload resolution" section. Any why two functions then?
I'm sorry, I don't know what that means.
So can you gove me an example of "controlling overload resolution" feature?
I just did. foo is enabled only when 'name' is convertible to char const*.
No. this is an example of type restriction. Overload resolution assimes at least 2 overloads, doesn't it?
First of all this is comparatevly rarely needed. Accordingly I do not see a reasons to supply library solution for this problem.
So we shouldn't care about this use case? Why? To reduce the number of lines of code in the implementation?
No. I just don't think it belong to this library at all. Especially if it's easier to implement without library.
Whould I ever need something like this, I would do:
template<typename Value> enable_if<Value is movable,void> foo_impl( Value const&, std::string name, Mymode mode ) { }
template<typename Params> void foo(Params const& p) { foo_impl( p[value], p[name], p[mode] ); }
value above is typelees keyword in my terminology. And no need to mix everything into one bowl.
But again, you don't generally have the ability to have a universal foo() overload that handles the dispatching. You want one for every overload.
You keep pressing that there maybe more that one foo. Why would I want to do this? Could you give an example? In my POV I onlt need one foo(Params const& p ) since it automatically cover all possible invokcation of function foo.
This is not exactly the same thing, and clear source of confusion.
Really? What's the difference?
Difference is this 8 out of 10 developers would ask where this 0 comes from? And what does it mean? 2 out of 10 wouldn't understant this code at all.
Ok. So what is your solution to the problem of supplying single named parameter based interface for dynamically sized series of functions with different actual number of arguments?
I would add something to the library to control overload resolution for this case with SFINAE.
I am getting an impression that you don't have even vague idea how would it look like. Could you come up at least with some pseudo code?
Why is that? Why Couldn't I do the same as what you are doing?
int v = params.has(a) ? params[a] : get_a_default_value();
It's even easier since I do not need to wrap it into bind call.
No, because get_a_default_value() has to compile. Our defaults can be lazily evaluated, and only compiled when needed.
Really? Is the parameter defaults also an implementation detail? As a user, how am I suppose to use your functions if I don't know about these things?
Yes. I inclined to think about function parameter default values more in terms of implementation details rather than part of interface. You as a function user shouldn't based your decisions on the default value for
Here is your code: double value_default() { return 666.222; } template<class Params> int f_impl(const Params& p) { p[tester]( p[name], p[value || boost::bind(&value_default) ] ); } Here is mine: double value_default() { return 666.222; } template<class Params> int f_impl(const Params& p) { p[tester]( p[name], p.has(value) ? p[value] : value_default() ); } In both cases default_value() needs to be compiled. Why my syntax is way better IMO. the
parameter: you have value for this parameter - you supply it. You don't - function deals with it itself. This is especially true since in many , many cases you just couldn't put default value into function declaration:
int foo( int a, int b = a ) {...}
What we do instead is somehow mimic similar behavior:
int foo( int a, int b = -1 ) { if( b = -1 ) b = a; }
So what default value -1 gives you as a function caller?
The value of 'a'?
And how caller should know that? And most importantly why?
What you were arguing here however is that it shouldn't even be part of the interface whether 'b' has a default value or is a required parameter.
In legacy C+ there are areseveral ways to make b "optional" .., int b = 2 ..., int b = invalid_value ..., int* b ..., optional<int> b = optional<int>() The only thing that is important is the fact that b is optional. This is interface part. The default value (if needed) is implementation detail. In my solution I mark keywords whether or not they name optional or requied parameters.
How? I would like to see it. I would like to see you to produce compile time error based on runtime value of the variable.
Of course I can't produce compile time errors based on runtime values, but who said anything about mode being a runtime value? The modes could just as well be tag types here, in which case it's trivial.
In many cases it's not acceptable.
template<class P> int select_impl(wait_t, P const& args) ..
template<class P> int select_impl(block_t, P const& args) ..
template<class P> int select_impl(pool_t, P const& args) ..
template<class P> int select(P const& args) { return select_impl(args[mode], args); }
Hey! Where is optional timeout handling? You code wouldn't compile if timeut is missing.
-- Daniel Wallin
Gennadiy