Take the 2-minute tour ×

This question on the object generator pattern got me thinking about ways to automate it.

Essentially, I want to automate the creation of functions like std::make_pair, std::bind1st and std::mem_fun so that instead of having to write a different function for each template class type, you could write a single variadic template template function that handles all cases at once. Usage of this function would be like:

make<std::pair>(1, 2);         // equivalent to std::make_pair(1, 2)
make<std::binder2nd>(&foo, 3); // equivalent to std::bind2nd(&foo, 3);

Is it possible to write this function make? I have tried this, but it doesn't work in GCC 4.5 or 4.6:

template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
    return TemplateClass<Args...>(std::forward<Args>(args)...);

If I try to call (e.g) make<std::pair>(1, 2) I just get

error: no matching function for call to 'make(int, int)'

Have I got the syntax wrong anywhere here?
Or is this right and GCC is wrong?
Or is this just fundamentally impossible in C++0x?


Proposal N2555 seems to suggest that this is allowed and GCC claims to have implemented it in GCC4.4.

share|improve this question
I think there was a problem, that variadic template template parameters will only match variadic template classes, IIRC. Also, mem_fn and bindNth will be obsolete and deprecated with C++0x, thanks to std::bind. –  Xeo Jun 26 '11 at 20:15
@Xeo: You mean a problem in GCC or the standard? N2555 suggests that it should be possible and GCC claims to have implemented it in 4.4 (see my edit) –  Peter Alexander Jun 26 '11 at 20:19
@Peter: A proposal doesn't say it has been adopted into the FDIS (but I sure hope it has). Let me check that. Edit: The FDIS has the wording from the proposal, so I don't know where the problem lies. –  Xeo Jun 26 '11 at 20:28
I'm wondering if there might be issues on how the template parameters are deduced? E.g., could it be that Args end up being reference types and this causes some SFINAE effect to discard your make function during resolution? –  bluescarni Jun 26 '11 at 20:46
@PeterAlexander: As the answers mentioned, this seems a bug of current gcc. For your information, by the use of auxiliary(meaningless?) class template, ideone(gcc-4.5.1) compiled it somehow. –  Ise Wisteria Jun 26 '11 at 21:34
show 14 more comments

3 Answers

up vote 15 down vote accepted

That's exactly right. I would expect it to work. So I think that GCC is in error with rejecting that. FWIW:

#include <utility>


int main() {

// [js@HOST2 cpp]$ clang++ -std=c++0x main1.cpp
// [js@HOST2 cpp]$
share|improve this answer
Looks like it's finally time for me to check out clang :-) –  Peter Alexander Jun 26 '11 at 20:52
add comment

This is probably a GCC quirk. I can get the following to work with a dev snapshot (I don't have a copy of 4.6 right now):

    template<typename...> class TemplateClass
    , typename... Args

    , typename Result = TemplateClass<Args...>
    // Also works with the arguably more correct
    // , typename Result = TemplateClass<
    //     typename std::decay<Args>::type...
    // >
make(Args&&... args)
{ /* as before */ }
share|improve this answer
add comment

This is quite wrong- take make_shared, for example. The point of make_shared is that there are run-time efficiency savings for using it. But what would happen if I tried to use make<std::shared_ptr>? Don't think that would quite work out. Or how about types where only some of the constructor arguments are template arguments, and the rest aren't? For example, make<std::vector, int>(other_vector.begin(), other_vector.end()); - the types of the iterators don't participate, but you pass them in anyway.

It's impossible to write a generic make function.

As for the Standard, well, it could easily have been removed since then. You'd have to check the FDIS.

share|improve this answer
The point is not to make a function that constructs any class, just the ones like I described: i.e. ones whose template parameters come entirely from constructor arguments. –  Peter Alexander Jun 26 '11 at 20:27
Theoretically, one could specialize the method for shared_ptr, but in general I agree this would cause more problems than it solves. –  Dennis Zickefoose Jun 26 '11 at 20:32
add comment

Your Answer


