tags:

views:

45

answers:

2

In code:

template<class T>
struct FactorPolicy
{
    T factor_;
    FactorPolicy(T value):factor_(value)
    {
    }
};

template<class T, template<class> class Policy = FactorPolicy>
struct Map
{
};

int _tmain(int argc, _TCHAR* argv[])
{
        Map<int,FactorPolicy> m;//in here I would like to pass a double value to a  
 //FactorPolicy but I do not know how.  
        return 0;
    }

Edited [for Mark H]

template<class T, template<class> class Policy = FactorPolicy>
struct Map : Policy<double>
{
    Map(double value):Policy<double>(value)
    {
    }
};
A: 

One way is to provide member function templates that take a template arg to use with the policy. For example:

template<class T, template<class> class Policy = FactorPolicy> 
struct Map 
{
  template <typename V>
  void foo(const Policy<V> &p)
  {
  }
}; 

Then, in main:

Map<int,FactorPolicy> m;

m.foo(FactorPolicy<double>(5.0));

Another possibility is to specify it as part of Map template instantiation, by adding a third template arg to Map:

template<class T, template<class> class Policy = FactorPolicy, 
         class V = double> 
struct Map 
{
  void foo(const V &value)
  {
    Policy<V> policy(value);
  }
}; 

Then:

Map<int,FactorPolicy,double> m;

m.foo(5.0);
Michael Goldshteyn
@Michael no I didn't, it is a template template class
There is nothing we can do
OK, so did what I specified for you _tmain function work out? Because the bottom line is you can't define a variable without specifying all of the (actual) template args.
Michael Goldshteyn
@Michael to your update, I'm not a 100% sure but if I declare a template template I don't have to provide params in template decl. But as I've said I'm not a 100% sure.
There is nothing we can do
For template template, your Map definition may be OK, but you definitely have to fill in all of the (template) args to use it for a variable definition.
Michael Goldshteyn
@Michael it won't compile what you've typed in _tmain. Just because it is template template. As I've mentioned this already.
There is nothing we can do
OK, your original code compiles just fine with VC++ 2010, so apparently there is nothing wrong with it other than compiler support in whatever compiler you are using.
Michael Goldshteyn
@Michael but there was never problem with compiling it. The whole problem is HOW TO PASS AN ARG TO A FactorPolicy ctor.
There is nothing we can do
I see, my misunderstanding, let me think a little more...
Michael Goldshteyn
@Michael no problem
There is nothing we can do
@Michael o just to let you know this arg is going to be of double type.
There is nothing we can do
I gave you some possible (correct) answers for your question, now that I fully understand it :).
Michael Goldshteyn
@Michael thanks for your answer but I want to avoid specifying separately the value of the policy (outside of the actual variable definition). If that wasn't the case I could build Map's ctor with a double type to be provided and this is even simpler than yours solution.;)
There is nothing we can do
If you do not want to go through these hoops, perhaps you are parameterizing Map too much? Perhaps you shouldn't use template template and just allow for a concrete type for Policy?
Michael Goldshteyn
@Michael let's assume that I would consider doing what've you suggesting. How then I could pass this arg?
There is nothing we can do
A: 

If you were to pass a double, it would require that the type argument of FactorPolicy be double inside Map, unless you make the FactorPolicy constructor to accept a double. I don't think that is what you want though. You must inform Map that Policy needs a double, so first add that type argument. Secondly, I think you will need to forward the actual double value from the Map constructor.

template<class T, typename U, template<class> class Policy = FactorPolicy >
struct Map {
    Map(U val) {
        policy_ = new Policy<U>(val);
    }

    Policy<U>* policy_;
};

int main()
{
    Map<int, double, FactorPolicy> m(5.63);
    return 0;
}
Mark H
@Mark if I would want to pass the factor value to the ctor I would do it even simpler - you do not have to specify U type.
There is nothing we can do
For what you are claiming, you would need to define it as `template<class T, class Policy = FactorPolicy<double> >`. Else how is Map going to know that FactorPolicy needs a double? It can't simply deduce that from the type of the argument, you must expicitly state the type somewhere.
Mark H
@Mark give me sec
There is nothing we can do
@Mark I've updated my answer.
There is nothing we can do
Your update requires you to pass an `int`. FactorPolicy still doesn't know what a `double` is.
Mark H
@Mark check it out now.
There is nothing we can do
But now Policy is non-generic. You can't use it with anything other than a double. (Unless you are using a different Policy to the one you're passing the double to)
Mark H
@Mark That's what I wanted, but if you change the double type to T it will also work as intended. The type will be deduced from Map ctor.
There is nothing we can do