C++ function template partial specialization?

c++ partial template specialization function
c++ function template specialization
partial template specialization c++
c++ template specialization member function
c template function specialization return type
template parameters not deducible in partial specialization
template specialization vs overloading
in instantiation of function template specialization

I know that the below code is a partial specialization of a class:

template <typename T1, typename T2> 
class MyClass { 
  … 
}; 


// partial specialization: both template parameters have same type 
template <typename T> 
class MyClass<T,T> { 
  … 
}; 

Also I know that C++ does not allow function template partial specialization (only full is allowed). But does my code mean that I have partially specialized my function template for one/same type arguments? Because it works for Microsoft Visual Studio 2010 Express! If no, then could you please explain the partial specialization concept?

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

template <typename T1, typename T2> 
inline T1 max (T1 const& a, T2 const& b) 
{ 
    return a < b ? b : a; 
} 

template <typename T> 
inline T const& max (T const& a, T const& b)
{
    return 10;
}


int main ()
{
    cout << max(4,4.2) << endl;;
    cout << max(5,5) << endl;
    int z;
    cin>>z;
}

In the example, you are actually overloading (not specializing) the max<T1,T2> function. Partial specialization syntax should have looked somewhat like below (had it been allowed):

//Partial specialization is not allowed by the spec, though!
template <typename T> 
inline T const& max<T,T> (T const& a, T const& b)
{                  ^^^^^ <--- specializing here
    return 10;
}

[Note: in the case of a function template, only full specialization is allowed by the C++ standard (excluding the compiler extensions).]

Function Templates Partial Specialization in C++, In the example, you are actually overloading (not specializing) the max<T1,T2> function. Partial specialization syntax should have looked somewhat like below  Fall back on class template partial specialization. Even if we can’t do partial specialization on function template, we can do it for class templates. And there is a way to achieve the former by reusing the latter.


Since partial specialization is not allowed -- as other answers pointed --, you could work around it using std::is_same and std::enable_if, as below:

template <typename T, class F>
inline typename std::enable_if<std::is_same<T, int>::value, void>::type
typed_foo(const F& f) {
    std::cout << ">>> messing with ints! " << f << std::endl;
}

template <typename T, class F>
inline typename std::enable_if<std::is_same<T, float>::value, void>::type
typed_foo(const F& f) {
    std::cout << ">>> messing with floats! " << f << std::endl;
}

int main(int argc, char *argv[]) {
    typed_foo<int>("works");
    typed_foo<float>(2);
}

Output:

$ ./a.out 
>>> messing with ints! works
>>> messing with floats! 2

Edit: In case you need to be able to treat all the other cases left, you could add a definition which states that already treated cases should not match -- otherwise you'd fall into ambiguous definitions. The definition could be:

template <typename T, class F>
inline typename std::enable_if<(not std::is_same<T, int>::value)
    and (not std::is_same<T, float>::value), void>::type
typed_foo(const F& f) {
    std::cout << ">>> messing with unknown stuff! " << f << std::endl;
}

int main(int argc, char *argv[]) {
    typed_foo<int>("works");
    typed_foo<float>(2);
    typed_foo<std::string>("either");
}

Which produces:

$ ./a.out 
>>> messing with ints! works
>>> messing with floats! 2
>>> messing with unknown stuff! either

Although this all-cases thing looks a bit boring, since you have to tell the compiler everything you've already done, it's quite doable to treat up to 5 or a few more specializations.

partial template specialization - cppreference.com, In C++, there are class templates and function templates. A partial specialization of (a) for pointer types there's no such thing as a partial specialization Template Specialization In many cases when working with templates, you'll write one generic version for all possible data types and leave it at that--every vector may be implemented in exactly the same way. The idea of template specialization is to override the default template implementation to handle a particular type in a different way.


What is specialization ?

If you really want to understand templates, you should take a look at functional languages. The world of templates in C++ is a purely functional sublanguage of its own.

In functional languages, selections are done using Pattern Matching:

-- An instance of Maybe is either nothing (None) or something (Just a)
-- where a is any type
data Maybe a = None | Just a

-- declare function isJust, which takes a Maybe
-- and checks whether it's None or Just
isJust :: Maybe a -> Bool

-- definition: two cases (_ is a wildcard)
isJust None = False
isJust Just _ = True

As you can see, we overload the definition of isJust.

Well, C++ class templates work exactly the same way. You provide a main declaration, that states the number and nature of the parameters. It can be just a declaration, or also acts as a definition (your choice), and then you can (if you so wish) provide specializations of the pattern and associate to them a different (otherwise it would be silly) version of the class.

For template functions, specialization is somewhat more awkward: it conflicts somewhat with overload resolution. As such, it has been decided that a specialization would relate to a non-specialized version, and specializations would not be considered during overload resolution. Therefore, the algorithm for selecting the right function becomes:

  1. Perform overload resolution, among regular functions and non-specialized templates
  2. If a non-specialized template is selected, check if a specialization exist for it that would be a better match

(for on in-depth treatment, see GotW #49)

As such, template specialization of functions is a second-zone citizen (literally). As far as I am concerned, we would be better off without them: I have yet to encounter a case where a template specialization use could not be solved with overloading instead.

Is this a template specialization ?

No, it is simply an overload, and this is fine. In fact, overloads usually work as we expect them to, while specializations can be surprising (remember the GotW article I linked).

C++ function template partial specialization?, How to use template specialization and partial specialization. (For more on manipulating bits directly, see bitwise operators and bit manipulations in C and C​++.) a function for comparison, you might specialize your template to handle these  the second function template has the same template parameters as the second partial specialization and has just one function parameter whose type is a class template specialization with all the template arguments from the second partial specialization. The function templates are then ranked as if for function template overloading.


Non-class, non-variable partial specialization is not allowed, but as said:

All problems in computer science can be solved by another level of indirection. —— David Wheeler

Adding a class to forward the function call can solve this, here is an example:

template <class Tag, class R, class... Ts>
struct enable_fun_partial_spec;

struct fun_tag {};

template <class R, class... Ts>
constexpr R fun(Ts&&... ts) {
  return enable_fun_partial_spec<fun_tag, R, Ts...>::call(
      std::forward<Ts>(ts)...);
}

template <class R, class... Ts>
struct enable_fun_partial_spec<fun_tag, R, Ts...> {
  constexpr static R call(Ts&&... ts) { return {0}; }
};

template <class R, class T>
struct enable_fun_partial_spec<fun_tag, R, T, T> {
  constexpr static R call(T, T) { return {1}; }
};

template <class R>
struct enable_fun_partial_spec<fun_tag, R, int, int> {
  constexpr static R call(int, int) { return {2}; }
};

template <class R>
struct enable_fun_partial_spec<fun_tag, R, int, char> {
  constexpr static R call(int, char) { return {3}; }
};

template <class R, class T2>
struct enable_fun_partial_spec<fun_tag, R, char, T2> {
  constexpr static R call(char, T2) { return {4}; }
};

static_assert(std::is_same_v<decltype(fun<int>(1, 1)), int>, "");
static_assert(fun<int>(1, 1) == 2, "");

static_assert(std::is_same_v<decltype(fun<char>(1, 1)), char>, "");
static_assert(fun<char>(1, 1) == 2, "");

static_assert(std::is_same_v<decltype(fun<long>(1L, 1L)), long>, "");
static_assert(fun<long>(1L, 1L) == 1, "");

static_assert(std::is_same_v<decltype(fun<double>(1L, 1L)), double>, "");
static_assert(fun<double>(1L, 1L) == 1, "");

static_assert(std::is_same_v<decltype(fun<int>(1u, 1)), int>, "");
static_assert(fun<int>(1u, 1) == 0, "");

static_assert(std::is_same_v<decltype(fun<char>(1, 'c')), char>, "");
static_assert(fun<char>(1, 'c') == 3, "");

static_assert(std::is_same_v<decltype(fun<unsigned>('c', 1)), unsigned>, "");
static_assert(fun<unsigned>('c', 1) == 4, "");

static_assert(std::is_same_v<decltype(fun<unsigned>(10.0, 1)), unsigned>, "");
static_assert(fun<unsigned>(10.0, 1) == 0, "");

static_assert(
    std::is_same_v<decltype(fun<double>(1, 2, 3, 'a', "bbb")), double>, "");
static_assert(fun<double>(1, 2, 3, 'a', "bbb") == 0, "");

static_assert(std::is_same_v<decltype(fun<unsigned>()), unsigned>, "");
static_assert(fun<unsigned>() == 0, "");

Why Not Specialize Function Templates?, This class takes two template parameters, a type parameter, and an expression parameter. Now, let's say we wanted to write a function to print out  Partial specialization allows template code to be partially customized for specific types in situations, such as: A template has multiple types and only some of them need to be specialized. The result is a template parameterized on the remaining types. A template has only one type, but a specialization is needed


No. For example, you can legally specialize std::swap, but you cannot legally define your own overload. That means that you cannot make std::swap work for your own custom class template.

Overloading and partial specialization can have the same effect in some cases, but far from all.

Template Specialization and Partial Specialization in C++ , template <class T, T t> struct C {}; // primary template template <class T> struct C<​T, 1>; Partial template specializations are not found by name lookup. s = 1; }; // partial specialization #1 // fictitious function template for #1 is // template<int I,  So the reason cannot be that function templates can only be fully specialized, because the third example is not a full specialization (the template parameter U is still there), and yet it works. c++ templates template-specialization partial-specialization


13.7, The compiler uses the partial specialization if its template argument list matches a subset of You cannot partially specialize function templates. int main() { X<​int, int, 10> a; X<int, int*, 5> b; X<int*, float, 10> c; X<int, char*, 10> d; X<float, int*,​  Well, you really can't do partial function/method specialization however you can do overloading. template <typename T, typename U> T fun(U pObj){} // acts like partial specialization <T, int> AFAIK // (based on Modern C++ Design by Alexandrescu) template <typename T> T fun(int pObj){} It is the way but I do not know if it satisfy you.


partial template specialization, 13.7.5 Class template partial specializations [temp.class.spec]. 1. # template A and the function template D is more specialized than the function template C. A function with the same name and the same argument list as a specialization is not a specialization (see template overloading in function template) . An explicit specialization of a function template is inline only if it is declared with the inline specifier (or defined as deleted), it doesn't matter if the primary template is inline.


Partial specialization, Template Specialization in C++ Template in C++ is a feature. We write code once and use it for any data type including user defined data types. For example, sort() can be written and used to sort any data type items.