4

I have a constructor prototype that looks like:

template <typename type_position> window(
    const int size[2],
    const char* caption="Window", const SDL_Surface* icon=NULL,
    bool fullscreen=false, bool vsync=true, bool resizable=false, int multisample=0,
    type_position position=type_position(0)
)

I then want to construct an instance:

new window(screen_size,"My Window",NULL,fullscreen);

The issue (I assume) is that T cannot be specified explicitly (i.e., it could be int or long or short, etc.). I get the error:

error C2660: 'window' : function does not take 4 arguments

I then tried to specify the type:

new window<int>(screen_size,"My Window",NULL,fullscreen);

But that doesn't work:

error C2512: 'window' : no appropriate default constructor available
error C2062: type 'int' unexpected

I've done some research, and about the closest I could get was similar to that is the question "C++ template function default value", except that in my case, the template parameter can be inferred from the first argument.

So, am I stuck or is there something I'm missing?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
geometrian
  • 14,775
  • 10
  • 56
  • 132

2 Answers2

2

You can't a provide explicit template argument list for a constructor, and a template parameter cannot be deduced from a default function argument, so the type_position position function parameter needs to be provided explicitly (not defaulted) in order to deduce the type.

As that is the final parameter, it prevents you using any of the contructor's default arguments. You could re-order the constructor parameters so the type_position is given first, or you could add a dummy argument that allows it to be deduced:

template <typename type_position> window(
  type_position dummy,
  const int size[2],
  const char* caption="Window", const SDL_Surface* icon=NULL,
  bool fullscreen=false, bool vsync=true, bool resizable=false, int multisample=0,
  type_position position=type_position(0)
);

Then call it with a dummy first parameter of the type to be deduced:

new window(1, screen_size,"My Window",NULL,fullscreen);

Alternatively, if you're using C++11, you can provide a default template argument:

template <typename type_position = int> window(
  const int size[2],
  const char* caption="Window", const SDL_Surface* icon=NULL,
  bool fullscreen=false, bool vsync=true, bool resizable=false, int multisample=0,
  type_position position=type_position(0)
);

Alternatively, decide if you really want a template constructor with a parameter that needs to be deduced. What do you plan to do with the type_position type if you don't know what it is in advance? Is it valid for someone to call that constructor with a std::string as the position parameter? Or a vector<double>? It might make sense, depending on what your type does, but it doesn't always make sense.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
0

The more I thought about it, it looks like you just need to provide a separate constructor:

window(
    const int size[2],
    const char* caption="Window", const SDL_Surface* icon=NULL,
    bool fullscreen=false, bool vsync=true, bool resizable=false,
    int multisample=0,
    int position=0
)
Jesse Good
  • 50,901
  • 14
  • 124
  • 166