
On Tue, 18 May 2004 00:17:40 -0400, christopher diggins wrote
I detect some frustration, I mean you no disrespect, I hold your work and comments in very high esteem.
No frustration, sorry it transmitted that way. Your statement was very broad, and implied that there are 'many problems' inheriting a template parameter. And yet I see it done sucessfully all the time in modern C++. Since I'm basically unaware of 'problems' with this approach your statement hit me much like the ever recurring programming guildeline: "Don't use multiple inheritance because it might create problems". Complete bunk that needs to be corrected...
I just changed the code by removing the public constraints typedef and adding a static function get_constraints() so that it can be invoked using instances of an object as well.
Well, ok, but I still don't like it.
The problem with parameter inheritance, as least in this case, is that it surprises programmers by causing an object to have an inconsistent interface.
This is really a matter of documentation. If I get used to calling mytype1::get_constraints().max() to find the max then I'm going to use my handy code editor to propagate this code around. As soon as I hit mytype2 that doesn't have constraints with a max function I'll be just as stumped as if mytype2::max didn't compile. Then I start looking at the docs and code to figure out what went wrong. But then I shouldn't expect a type with a name like 'divisible_by_four' to necessarily have a min/max interface.
Most programmers when confronted with code such as mytype::max() expect that max will be available for all instances of mytype.
I assume here mytype refers to the constrained_value template? Because for a given user type generated from this template mytype::max will be available for all instances.
On the other hand, mytype::get_constraints().max() is generally understood to not always be readily available in a parameterized type.
Really? Let's say I've never seen the documentation for constrained_value and I'm just reading some code I didn't write. For me, I have to think for an extra nano-second ( little joke :) about the meaning of this code: mytype::get_constraints().max() I'm thinking let's see, a static function that returns an object with a max function. As opposed to just -- yeah, get the max. mytype::max()
I don't see how the advantage of the shorthand justifies the case for parameter inheritance here.
I'll turn it around the other way -- I don't see how the 'longhand' makes the interface any clearer. The interface still needs a description the user can understand. In any highly flexible template design this is always more difficult. One last point. By inheriting from the policy, we can both have our way. You can specilize your constraint policy to have a public method 'get_contraints' that returns an object and I can have my min/max. Now that's power ;-) Jeff