Default parameters can vary between translation units, which is
not good for code clarity. They can also cause address-of-function
problems and binary compatibility problems. An overload set is a
significantly better approach to the problems that default parameters
solve. I would rather the user wrote function overloads to handle
the various cases. Mostly, you can do this in an API-compatible
manner. So, rather than extend a flawed feature, I would rather say
"do not do that".
void foo(int param, optional<type1> value1, optional<type2> value2) {
type1 val1 = value1.value_or(a1);
type2 val2 = value2.value_or(a2);
//implementation
}
void usefoo() {
foo(0, nullopt, b2);
}
Personally, I don't think that default parameters are a "flawed feature". That being said, the flaws discussed are not resolved by your suggestion.
Default parameters solve a simple, very specific problem. Function overloading solves a larger, more general problem. I like that we have both. And I think that the problem that you intend to solve, with some kind of "default" parameter, is best solved with the larger, more general solution.
Also, with `optional`:
void foo(int param, optional<type1> value1, optional<type2> value2) {
type1 val1 = value1.value_or(a1);
type2 val2 = value2.value_or(a2);
//implementation
}
void usefoo() {
foo(0, nullopt, b2);
}
That seems to take care of the problem.
//foo.h
void foo(int a, type1 param1, type2 param2 = value2);
//foo.cpp
void foo(int a, type1 param1, type2 param2) {
//Is param1 value1 or value3?
}
//usefoo1.cpp
static void usefoo1() {
foo(1, value1);
}
//usefoo2.cpp
static void usefoo2() {
foo(1, value3);
}
Yes, that doesn't work. I agree. And it should never work.
Re-declaring functions with different default parameters is a horrible idea. Default parameters should be considered part of a function's interface.
What you're trying to do is a wrong thing. Default parameters are a tool for the person implementing the function, not for person calling it. If you want to have some helper function in a source file that uses other defaults that are local to that source file, the declare a helper function that fills in the default for you:
//foo.hstatic void usefoo1() {
void foo(int a, type1 param1, type2 param2 = value2);
//foo.cpp
void foo(int a, type1 param1, type2 param2) {
//Is param1 value1 or value3?
}
//usefoo1.cpp
foo(1, value1);
}
//usefoo2.cpp
static void usefoo2() {
foo(1, value3);
}
See? That wasn't hard. Your default parameters are there, and any compiler worth using will likely inline them for you.
The C++ committee ought not add features to support this usage pattern for default parameters.
Yes, that doesn't work. I agree. And it should never work.
Re-declaring functions with different default parameters is a horrible idea. Default parameters should be considered part of a function's interface.
I personally do not like to re-declare functions like that. But it's the choice of the individual.
Default middle parameter proposal neither encourages nor discourages such usage pattern. If such a pattern should not be supported then that should be deprecated and removed subsequently instead of allowing the users to do it and also making it difficult to do it. The use case for this proposal is not this re-declaration case. It is just that it makes it easy to use that function.
//foo.hstatic void usefoo1() {
void foo(int a, type1 param1, type2 param2 = value2);
//foo.cpp
void foo(int a, type1 param1, type2 param2) {
//Is param1 value1 or value3?
}
//usefoo1.cpp
foo(1, value1);
}
//usefoo2.cpp
static void usefoo2() {
foo(1, value3);
}
See? That wasn't hard. Your default parameters are there, and any compiler worth using will likely inline them for you.
The C++ committee ought not add features to support this usage pattern for default parameters.
void foo(int a, type1 param1 = value1, type2 param2 = value2);Assume that 50% of the users set param1 to value3 and want default value for param2 and the rest set param2 to value4 and want default value for param1. Because of the order of the declaration of parameters only 50% of the users will find it easier to use.
It's only a "choice of the individual" because of the limitations of the C++ language. It was never the intent of the language to allow users to arbitrarily re-declare default parameters like that. It is simply an outgrowth of what is possible, as necessitated by the way the language works.
To make default parameters operate as efficiently as non-default parameters, it was necessary for them to be something that is part of the function declaration. That way, the compilation of the calling source code would fill in the extra parameters, rather than some centralized code. Coupled with the fact that the function definition is not linked to these default parameters (it's not a part of the function's type), it becomes possible to re-declare functions with different default parameters.
This was not what was intended. It's merely an outgrowth, an accident.
It should not be supported or encouraged.
But the re-declaration case is exactly what makes the optional method not work. If you remove the silly re-declaration stuff, then the optional method would work perfectly fine.
So if your use case is not about re-declaration, then why is it that `optional` won't solve the problem?
(FYI: the correct answer to the question I just asked is, "what do you do about reference parameters, like `const T&`?")
Or they can just use `foo(val, nullopt, value4);` with the previously discussed `optional` method. See? It's the re-declaration that made the optional method fail.
Le 29/04/13 12:15, Hariharan Subramanian a écrit :
--
--- You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/4tWQEMqEH8s/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
On Wed, May 1, 2013 at 3:35 AM, Vicente J. Botet Escriba <vicent...@wanadoo.fr> wrote:
Le 29/04/13 12:15, Hariharan Subramanian a écrit :
Solution:
Introduce the default keyword during the function call. The function call becomes
void usefoo() {
foo(0, default, b2);
}
This should also work
// header
namespace detail {
foo_value1_default() {return a1};
}
void foo(int param, type1 value1 = foo_value1_default(), type2 value2 = b1);
void foo(int param, type2 value2 = b1) {foo(param, foo_value1_default(), value2);}
//usage
foo(0);
foo(0, b1);
foo(0, b1, b2);
foo(0, b2);
It requires minor gymnastic for the implementer, but from the user point of view it provides what you where locking for.
If my understanding of your solution is correct, the number of functions an implementer has to write is exponential in the size of the number of default parameters. I think it's a subset problem.
You are right, if the number of defaulted parameters is big, but I would not try to solve this problem changing the language.
The alternative to avoid all the overload that is close to your default would be for the user to use the foo_value1_default.
foo(0, foo_value1_default(), b2);
This is less elegant, but do you really think that it is worth changing the language to improve it?
If named parameters were there would you request this feature?
I think it's an excellent idea. Simple and obvious. Which means that its chances of being accepted in this forum are very slim, I'm afraid!
--
---
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/4tWQEMqEH8s/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.
Named parameters solves this problem. But introducing named parameters only for this would be an overkill. Even otherwise, I think named parameters is unnecessary. Cannot the IDE simply display the name of the parameter adjacent to the parameter passed? No need to change the language at all. Named parameters would have been useful during the 1990s but not now.Regards,Hariharan S
void foo(int=0, int=1, int, int, int) {}
foo(default, default, 2, 3, 4);
foo(10, default, default, default, 12, default);
foo(10, , , , 12);
The IDE showing names doesn't help much. The difference is:
foo(10, default, default, default, 12, default)vsfoo(.x = 10, .z = 12)Some people might find the second easier to read and understand. (And some might prefer the first because it doesn't "hide" as much.)
Why would we have to chose between the proposed idea and named parameters? Both are interesting. The proposed idea doesn't get in the way of those preferring named parameters (if they ever get into the standard...).Personally I like it; it's simple, doesn't add complexity and doesn't get in the way of anything. It is not because there are workarounds and that we could live without it that it should not be considered (think about range-based for loops; they were never "needed" but they were added).
About the proposed idea, two things that cross my mind.1. Default for first parameters (and not only last ones).It could now also be possible to have default parameters which are not the last ones. This is something new that I would put in the same proposal. For example:
void foo(int=0, int=1, int, int, int) {}
foo(default, default, 2, 3, 4);Of course there would be no way to use those default values without using the "default" keyword. (or by using the alternate syntax; see 2.)
2. Omitting parameter instead of the "default" keywordWhy not calling without any keywords between the comas to signify to use the default? Example from the previous post:
foo(10, default, default, default, 12, default);would become:
foo(10, , , , 12);Some might prefer it, some might dislike it and stick with the "default" keyword and some would allow both. Personally I don't have anything against any of these options.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
Any IDE solution assumes you are using an IDE which is just one way of doing things. It is not the only way of doing things. And this also assumes that the IDE is also used for other tasks (e.g. code reviews).
--
---
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/4tWQEMqEH8s/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.
On Thu, May 2, 2013 at 8:28 PM, Vincent Jacquet <vjac...@flowgroup.fr> wrote:
Actually, named parameters exists in several languages (see <http://en.wikipedia.org/wiki/Named_parameter>). Visual Basic had it for a while and it's been added recently in C# 4.As far as I know, one of the main reason to add named parameters in c# was to improve interop with COM, as quite a few methods have a lot of parameters. You might want to take a look at the ConvertToTable method on page http://msdn.microsoft.com/en-us/library/dd264738.aspx). It has lots of parameters therefore named parameters are very usefull for readability in this context.
Yet I am not sure we need this in c++. I think we have better alternatives, such as, for instance, declaring a ConvertToTableSettings struct.As for allowing "default" parameter in the middle, it has some appeal. I mean it is "not fair" that I must omit value2 if I want to omit value1 (using you example).But we are speaking of "foo" functions. Do you have real life cases where you want to do that?
What I meant by "other programming languages do not have this feature" was default middle param value and not named params.
Thanks for the info Greg. Will you able to offer comments on the assertion "the combination of this proposal and named parameters may encourage interfaces with high number of parameters"?
Tony
--
---
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/4tWQEMqEH8s/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
During the lifecycle of a software, the default value of a parameter can change. If the
default value of type2 changes then no work need to be done. But if the default
value of type1 changes then wherever a1 was used it should be changed.
--