[parameter] - catching accidental duplicate parameters at compile time

To take the first code snippet from the tutorial: new_window("alert", width=10, titlebar=false); Suppose the user accidentally does this: new_window("alert", width=10, titlebar=false, width=2); In the current version of the library this compiles, and by examining the source of the library we can discover that one of the values for 'width' will be used and the other discarded (working out which is left as an exercise for the reader.) It would be nice if this was caught at compile time - especially if the parameter "values" are complex expression templates, making it hard to spot the problem at first glance. One implementation would be to add a recursive metafunction to the body of arg_list: template<class SAME_AS> struct find_duplicates { enum { value = (boost::is_same<SAME_AS, key_type>::value || Next::template find_duplicates<SAME_AS>::value) }; }; BOOST_STATIC_ASSERT(!(Next::template find_duplicates<key_type>::value)); And a terminator to empty_arg_list: template<class SAME_AS> struct find_duplicates { enum { value = false }; }; So an arg_list instantiation will not compile if it adds itself to the front of a list that already contains an arg_list entry using the same keyword type. Hope this is worthwhile. --Daniel.

Daniel Earwicker <daniel.earwicker@gmail.com> writes:
To take the first code snippet from the tutorial:
new_window("alert", width=10, titlebar=false);
Suppose the user accidentally does this:
new_window("alert", width=10, titlebar=false, width=2);
In the current version of the library this compiles, and by examining the source of the library we can discover that one of the values for 'width' will be used and the other discarded (working out which is left as an exercise for the reader.)
Are you sure that's true even for conforming compilers? On conforming compilers, the library uses overloading to look up the value associated with any given keyword. I assumed that having two of the same keyword would cause an ambiguity error at lookup time: args[width]
It would be nice if this was caught at compile time - especially if the parameter "values" are complex expression templates, making it hard to spot the problem at first glance.
One implementation would be to add a recursive metafunction to the body of arg_list:
template<class SAME_AS> struct find_duplicates { enum { value = (boost::is_same<SAME_AS, key_type>::value || Next::template find_duplicates<SAME_AS>::value) }; };
BOOST_STATIC_ASSERT(!(Next::template find_duplicates<key_type>::value));
And a terminator to empty_arg_list:
template<class SAME_AS> struct find_duplicates { enum { value = false }; };
So an arg_list instantiation will not compile if it adds itself to the front of a list that already contains an arg_list entry using the same keyword type.
The problem with this (aside from the use of an ALL_CAPS name for something other than a macro) is that it costs O(N^2) instantiations, where N is the number of arguments. OTOH you could do it with overloading (or just use an mpl::set, which uses overloading internally) to do it in O(N). -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
Daniel Earwicker
-
David Abrahams