C++ Logo

std-proposals

Advanced search

Re: Function partial template specialization

From: Jorg Brown <jorg.brown_at_[hidden]>
Date: Mon, 9 Sep 2019 15:01:27 -0700
It took me a long time to really wrap my head around the fact that almost
every time you think you need function template specialization, function
overloading will give you what you need.

Part of that process was realizing that, once you have the power of
function overloading, which you don't have with templated classes, it
becomes a problem for function template specialization to realize precisely
which function template you're specializing.

In any case, in the extremely rare cases where overloading doesn't work,
you can definitely always make a functor, rather than a function, that
works.

On top of that, ever since C++17, the power of "if constexpr", combined
with a function return type of "auto", fills in any gray area you think
might exist.

In your first example:

template <int N, class T>
void function(void) {
  T t;
  GeneralCode(N, &t);
}

template <class T>
void function<42, T>(void) {
  T t;
  CodeFortyTwo(&t);
}


You could also implement it using functors:

template <int N, class T>
struct functor {
  void operator()(void) const {
    T t;
    GeneralCode(N, &t);
  }
};
template <class T>
struct functor<42, T> {
  void operator()(void) const {
    T t;
    CodeFortyTwo(&t);
  }
};

template <int N, class T>
void function(void) {
  functor<N, T>{}();
}

Or with function overloads:

template <class T, int N>
void function_overload(std::integral_constant<int, N>) {
  T t;
  GeneralCode(N, &t);
}

template <class T>
void function_overload(std::integral_constant<int, 42>) {
  T t;
  CodeFortyTwo(&t);
}
template <int N, class T>
void function(void) {
  function_overload<T>(std::integral_constant<int, N>{});
}

(But note that typically you wouldn't need an extra overload, in particular
if your function takes a type and you're using template argument deduction
based on that type, overloading works very naturally and without the need
to add a second function name.)

But with "if constexpr", this becomes quite trivial:

template <int N, class T>
void function(void) {
  T t;
  if constexpr(N == 42) {
    CodeFortyTwo(&t);
  } else {
    GeneralCode(N, &t);
  }
}


This brings me back to the end of your message, where you write:

> This could be very useful in some situation

The bar for adding a feature to C++ is much, much higher than this. A
typical proposal contains a line more like:

"This is extremely useful in this situation ..."
or
"This is very tedious with the current language standard, but becomes
simple and clean after this proposal"


Which is to say, the committee will want to know much more about what
situation would be helped, and will insist that more currently-available
alternatives be considered, before discussing any additional language
feature.

-- Jorg

On Mon, Sep 9, 2019 at 1:17 PM develop--- via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hello,
> I had some probems with template specialization, so I have a proposal:
> allow partial template specialization for function and ordinary members of
> a templated class.
>
> In some situation it could be useful to define partial template
> specialization for functions, for example:
>
> template <int N, class T>
>
> void function(void);
>
>
> template <int N, class T>
>
> void function<N, T>(void) {}
>
>
> template <class T>
>
> void function<42, T>(void) {}
>
> In other situations you may want to create a class with methods whose
> behaviour depends on the template parameters, for example:
>
> template <int N, class T>
>
> class Foo
>
> {
>
> // #1
>
> void test(void);
>
> // ...
>
> };
>
>
> template <class T>
>
> class Foo<2, T>
>
> {
>
> // #2
>
> void test(void);
>
> // ...
>
> };
>
>
> template<int N, class T>
>
> void Foo<N, T>::test(void) { /* belongs to #1 */ }
>
>
> template<class T>
>
> void Foo<7, T>::test(void) { /* belongs to #1 */ }
>
>
> template<class T>
>
> void Foo<2, T>::test(void) { /* belongs to #2 */ }
>
> This could be very useful in some situation, such as creating a vector or
> a matrix class where you need some common methods and you want to partially
> specialize them for few cases. Of course it is possible to use some other
> strategies, for example declaring a partially specialized copy of the
> classes for each case, but it would be tedious, error prone end it could
> create some difficulties in maintainance.
>
> Why does the standard currently non feature this?
> Do you believe such a proposal would makes sense? I think this would imply
> only few changes, am I right?
>
> Thanks for consideration.
>
> Best regards,
> Luca Ciucci.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2019-09-09 17:03:47