1

suppose I have a lot of classes with their "*Pack" counterparts in naming. For example, if I have a class Moo, I have MooPack, if I have Foo, I also have FooPack.

I want to have a c++ templated function which returns a FooPack from a Foo

template <class X, class XPack>
XPack packify(X input){
   ...
}

Is it possible to do this without having to specify the template argument? At the moment, this has to be done like the following:

Moo moo;
MooPack mooppey = packify<Moo, MooPack>(moo);

If it only required the Moo template argument, that ugly template specification bit could go away, but apart from using #defines, which isn't really the best solution either, still doesn't do it.

Is there a way, or will I have to wait for c++0x?

2 Answers 2

5

You don't have to specify Moo, just MooPack, because moo will deduce the argument for you. However, I'd suggest that you make MooPack a typedef or nested class (called Pack) inside Moo itself, in which case you can easily access it by typename X::Pack inside the template.

class Moo {
public:
    class Pack {
        ...
    };
};
template<typename T> typename T::Pack packify(T t) {
    ...
}

// usage

Moo m;
Moo::Pack p = packify(m);
Sign up to request clarification or add additional context in comments.

2 Comments

Ah yes, I think specifying only one argument is actually acceptable enough (two args just look ugly). That nested class thing is a great idea, but I can't change the existing class declarations..
You don’t even need to nest the *Pack class, you just need to provide a nested typedef to it. The usage is the same as in the above example. This is a pretty common pattern (called “metafunction”).
1

As the answer by DeadMG already mentioned you don't need to explicitely specify the parameter type as it can be deduced automaticaly (if it's the second instead of the first template parameter). Since you said you can't change the type declarations to form a link between the classes, I would propose the traits route for that (think std::iterator_traits):

template<typename T> struct pack_traits;
template<> struct pack_traits<Moo> { typedef MooPack Pack; };
...//traits for other packifable classes

template<typename T> pack_traits<T>::Pack packify(T val){...}
...
Moo moo;
MooPack mooppey = packify(moo);

This way you can call the function without manually specifying template arguments, without needing to modify the classes themselves.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.