Alex Rivera | Logout

Why aren't named parameters used more often?

Asked 2012-04-05T23:57:21.933
9

I have designed a parameter class which allows me to write code like this:

//define parameter
typedef basic_config_param<std::string> name;

void test(config_param param) {

  if(param.has<name>()) { //by name
    cout << "Your name is: " << param.get<name>() << endl;
  }

  unsigned long & n = param<ref<unsigned long> >(); //by type
  if(param.get<value<bool> >(true)) { //return true if not found
    ++n;
  }
}


unsigned long num = 0;
test(( name("Special :-)"), ref<unsigned long>(num) )); //easy to add a number parameter
cout << "Number is: " << num; //prints 1

The performance of the class is pretty fast: everything is just a reference on the stack. And to save all the information I use an internal buffer of up to 5 arguments before it goes to heap allocation to decrease the size of every single object, but this can be easily changed.

Why isn't this syntax used more often, overloading operator,() to implement named parameters? Is it because of the potential performance penalty?

One other way is to use the named idiom:

object.name("my name").ref(num); //every object method returns a reference to itself, allow object chaining.

But, for me, overloading operator,() looks much more "modern" C++, as long you don't forget to uses double parentheses. The performance does not suffer much either, even if it is slower than a normal function, so is it negligible in most cases.

I am probably not the first one to come up with a solution like this, but why isn't it more common? I have never seen anything like the syntax above (my example) before I wrote a class which accepts it, but for me looks it perfect.

Edit
Report

2 Answers

59

My question is why this syntax is not used more, overloading operator,() to implement named parameters.

Because it is counter-intuitive, non-human-readable, and arguably a bad programming practice. Unless you want to sabotage the codebase, avoid doing that.

test(( name("Special :-)"), ref<unsigned long>(num) ));

Let's say I see this code fragment for the first time. My thought process goes like this:

  1. At a first glance it looks like an example of "the most vexing parse" because you use double-parentheses. So I assume that test is a variable, and have to wonder if you forgot to write variable's type. Then it occurs to me that this thing actually compiles. After that I have to wonder if this is an instance of an immediately destroyed class of type test and you use lowercase names for all class types.
  2. Then I discover it is actually a function call. Great.
  3. The code fragment now looks like a function call with two arguments.
  4. Now it becomes obvious to me that this can't be a function call with two arguments, because you used double parentheses.
  5. So, NOW I have to figure what the heck is going on within ().
  6. I remember that there is a comma operator (which I haven't ever seen in real C++ code during the last 5 years) which discards the previous argument. SO NOW I have to wonder what is that useful side effect of name(), and what the name() is - a function call or a type (because you don't use uppercase/lowercase letters to distinguish between class/function (i.e. Test is a class, but test is a function), and you don't have C prefixes).
  7. After looking up name in the source code, I discover that it is class. And that it overloads the , operator, so it actually doesn't
    answered 2012-04-06T01:18:04.220
3

There is not necessity. Your dynamic dispatch (behave differently, depending on the logical type of the argument) can be implemented a) much easier and b) much faster using template specialisation.

And if you actually require a distinction based on information that is only available on runtime, I'd try to move your test function to be a virtual method of the param type and simply use dynamic binding (that's what it's for, and that's what you're kind of reinventing).

The only cases where this approach would be more useful may be multiple-dispatch scenarios, where you want to reduce code and can find some similarity patterns.

answered 2012-04-06T00:12:06.980

Your Answer