2

I need to instantiate a templated function foo() with a long signature, for some specific template arguments.

I just read the answers to this question which essentially suggest copying the function signature but setting the specific arguments. I want to avoid that somehow. What is a reasonable way to achieve this? e.g. something which would allow me to write

INSTANTIATE(foo, template_arg1, template_arg2);

or maybe

MyFunctionType<template_arg1, template_arg2> foo;

Just for illustrative purposes, suppose this is the code for foo:

template<typename T, int val>
unsigned foo(
    T bar,
    SomeType baz1,
    SomeOtherType baz2,
    YetAnotherType you_catch_the_drift) 
{ 
    /* some code here */ 
}
Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • @jrok: I don't think it matters, but see my edit now. – einpoklum Mar 25 '14 at 09:13
  • In C++11 you could use template aliases to make an alias to your function type partially parametrized. This helps if your function has too many parameters, but some of them are well known (Used frequently) but some others are not and should be specified by the user of the function type. – Manu343726 Mar 25 '14 at 09:48
  • The same applies for the function usage, not only the instantation/declaration of its type. You could use std::bind() to bind well known parameters and reduce the number of parameters the user should specify at the call point. – Manu343726 Mar 25 '14 at 09:50
  • 1
    @Manu343726: Can you give example code? Also, I could make the return type very long and tedious, e.g. std::tuple, std::vector>` or something. – einpoklum Nov 18 '14 at 07:25

2 Answers2

0

In explicit instantiations of function templates it's possible to omit the template parameter list after template-id if all arguments can be deduced:

template<typename T> void foo(T) {}
template void foo(int); // explicit instantiation
//               ^ no template parameter list here

Not in your case, though, since val parameter needs to be passed explicitly. This is how your explicit instantiation could look like:

template unsigned foo<int, 0>(int, char, double, float);

Is it that bad? You can write a macro to avoid some duplication, but looks like there isn't much of it in the first place.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
jrok
  • 54,456
  • 9
  • 109
  • 141
  • And just to be clear - if I write this line - which looks like a declaration of a specialization - it would instantiate the template? That is, I would see foo in my objdump output? – einpoklum Mar 25 '14 at 09:41
  • @phresnel Yeah, I guess I'm not completely awake just yet :) – jrok Mar 25 '14 at 09:48
  • @einpoklum Yes, this feature is called [explicit instantiation](http://stackoverflow.com/questions/2351148/explicit-instantiation-when-is-it-used). – Constructor Mar 25 '14 at 14:04
  • @einpoklum And syntax of it is a bit different from a declaration of a specialization. – Constructor Mar 25 '14 at 14:10
  • This still means that if my function signature changes, I need to change all of these explicit instantiations. Can't I use `decltype` or something similar instead? – einpoklum Jan 08 '15 at 08:10
0

You can simply define a macro:

#define INSTANTIATE_FOO(T, val) \
template \
unsigned foo<T, val>( \
    T bar, \
    SomeType baz1, \
    SomeOtherType baz2, \
    YetAnotherType you_catch_the_drift);

And use it in the following way:

INSTANTIATE_FOO(int, 0)
Constructor
  • 7,273
  • 2
  • 24
  • 66