
Rozental, Gennadiy wrote:
I thought I'd try an example to see what happens. whether this is best example I dont know....whatever Many more variants of course possible. operator()() could be moved into multiply_traits etc which would give user yet more control. Perhaps that is the difference. Move all the implementation out of the class gives the user more flexibility. But is it the flexibility that se wants. (Sorry boost pros uses she above, but men users, women developers, viceversa...just a personal thing)
First observation from below ....Obviously the application has a great deal to do with it.! :-) Many more experiments to do ... but ... Interesting debate.
regards Andy Little
-----------
#include <iostream> template< typename A , typename B > struct multiply_traits;
// use traits template< typename A , typename B > struct multiply1{
typedef multiply_traits<A,B> traits; typename traits::result_type operator () (typename traits::first_argument_type a, typename traits::second_argument_type b) { return a * b; }
}; //use policy template< typename A , typename B, typename Policy> struct multiply2{
typename Policy::result_type operator () (typename Policy::first_argument_type a, typename Policy::second_argument_type b) { return a * b; }
// or Policy ()(a,b); etc if ---> policy
};
And give me single example where second design is preferable to first?
Actually I think the best design would look like this:
namespace {
struct multiply_t { template< typename A , typename B > struct sig : multiply_traits<A,B> {};
template< typename A , typename B > typename sig<A,B>::result_type operator ()( typename sig<A,B>::first_argument_type a, typename sig<A,B>::second_argument_type b ) { return a * b; } } multiply;
}
int main() { std::cout << multiply( 10, 1.5 ) <<'\n';
MyInt i( 10 ) std::cout << multiply( i, 10 ) <<'\n'; }
The problem with your solution is that it arbitrarily restricts the degrees of freedom a client has, all in the name of "a trait is a trait, and a policy is a policy." Suppose I have two contexts in which I need to multiply two unsigned chars together. In context one, I want the result type to be unsigned char, because in this context I'm using modulo arithmetic. In context two, I want the result type to be int, because here I'm using ordinary arithmetic. It seems pretty easy to me to do this with "multiply2" above by passing in different policies. Using your solution, I cannot customize the return type this way. Bob